UnderwareDESIGN

PlayBASIC => Show Case => Topic started by: kevin on April 22, 2012, 12:07:12 AM

Title: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: kevin on April 22, 2012, 12:07:12 AM

(http://underwaredesign.com/PlayBasicSig.png)


PlayBASIC V1.64N2 & V1.64N3  (Work In Progress) Gallery


    This thread will document the changes being made for the PlayBASIC 1.64 revision N2 and revision N3 (Last half of thread).    Ideally this update will address a few issues in the V1.64N release, with probably some more tweaks thrown in for good measure.

    For Newer upgrade work in progress see,

     See  [plink]PlayBASIC V1.64P (http://www.underwaredesign.com/forums/index.php?topic=4089.0)[/plink]   -     Convert PlayBASIC To Machine Code Dll's (http://www.underwaredesign.com/?l=PlayBASIC-To-DLL-Development-Blog)

    See  PlayBASIC V1.64O (http://www.underwaredesign.com/forums/index.php?topic=3988.0)


    For older upgrade work in progress see,

    See  PlayBASIC V1.64N (http://www.underwaredesign.com/forums/index.php?topic=3651.0)

    See  PlayBASIC V1.64M (http://www.underwaredesign.com/forums/index.php?topic=3440.0)

    See  PlayBASIC V1.64L Learning Edition History (http://www.underwaredesign.com/forums/index.php?topic=3405.0) (Building learning Edition Thread)

    See  PlayBASIC V1.64L  (http://www.underwaredesign.com/forums/index.php?topic=3364.0)





PlayBASIC V1.64N2  Beta #1 - Sprites Collision and evils branch prediction

    While roaming the hill sides of the PB engine a few weeks back,  noticed something of an oddity in regards to sprite collision, in particular when used in scenes of say 500->1000 sprites.   Yeah, I guess that's a fairly pie in the sky sprite count given your average PB has has less than 25 sprites on screen, but none the less,  if we can make a dent on the bottle neck then any improvement will flow through to more real world situations.

    In the test code, I'm creating a 1000 sprites within a 800 * 600 range of each other and comparing each sprite to all 1000 of them,making a 1,000,000 brute force potential impacts.   What's interesting is that in this situation, it's actually quicker to not use collision classes at all,  by about 3 times in fact.    

    When sprite hit runs through the set, it's just AND'ing the your desired class with each sprites class , if no bits are shared, we skip it.

    Which might look a bit like this in PB code



   MyMASK = %11110000

   For ThisSprite =1 to  NumberOfSprites
        if GetSpriteCollisionClass(ThisSprite)   and MyMASK

             ; Here we'd continue to do the actually impact
             
       endif
   next



     So what we're saying is that when the IF / ENDIF statement is always true, then the loop runs much quicker (3 times faster) than when the we selective target impacts, when say only 10% of the cases were true.   Doesn't make sense ?, yeah... had me stumped for a while, but this has all the hall marks of the branch predictor failing us.     Which I'm not too sure we can avoid at this point.  I've been trying to rearrange the logic to avoid potential stalls, but the moment there's a comparison in the loop it dies in such circumstances.
         
     Now given the situation is pretty pie in the sky,  it's not really something i'm worried about, but it does bother me :)

 
     Attached is pic showing the scene i'm testing.. a bit over the top :)

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on April 22, 2012, 08:09:13 AM
one thousand sprite, good work, and how many fps?
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on April 22, 2012, 08:58:48 PM

about 30
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on April 22, 2012, 09:33:39 PM
 PlayBASIC V1.64N2  Beta #2 - Compare Operators

     A by product of the previous test has lead to some improvements to the compare operator opcodes in the PB VM.    Compares aren't a heavily used operator throughout a program, but they generally appear in high repetition loops, so we can win back some free performance by customizing the opcodes to better handle the most general situation, which is INTEGER compares.   It'll still handles mixed INT/FLOAT types, but the reshuffle means it's slightly biased towards integer operations.

     In the shots bellow we're running a bunch of for/next loops each  performing 10,000 iterations.   Each test is comparing the various comparison types, so we've a loop for EQUALS, NOT EQUAL, LESS THAN, GREATER THAN,  LESS THAN EQUALS and GREATER THAN EQUALS.   Some loops are just doing one compare, others are comparing all 4 combination.. ie. INT=INT, INT=FLT, FLT=INT, FLT-FLT
           
    The compiler can also detect some assignment redundancy in expressions, which can remove the odd bogus move operator that could appear in the outputed code.    The combination makes the bench mark about twice as fast.   May have also found a few legacy opcodes no longer in use.  It's hard to tell really, since the output opcode is often calculated (merged) during code generation, rather than  a nice an obvious write function.  So if you get 'messages during BETA testing' then I wanna know about it.  



PlayBASIC V1.64N2  Beta #3 - FOR / NEXT Statements

    While looking through some user code recently, noticed a few usages of   STEP 1 in FOR/NEXT loops.  The run time actually has two looping methods built in, one for the default loop iteration of one, and another for a user defined step value.  This is necessary as the user defined step requires another variable read from memory every iteration.   Fetching from memory is unavoidable when the step is some custom value, but when it's one, it's just overhead for the sake of overhead.  So the parser now automatically detects this situation and defaults back to the standard +1 looping form.          
    So this,


     For lp =0 to Max Step 1
          Count++
     next

 
     is actually compiled as this now.

     For lp =0 to Max
          Count++
     next




Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on April 24, 2012, 02:18:03 AM
 PlayBASIC V1.64N2  Beta #4 - Squeeeeezzzzzing out some extra Loop performance

     At this stage,  optimizing any of the core operations in the PBV1.64 VM,  is how you'd imagine those formula one engineers must feel squeezing that extra millisecond out of their latest F1 car.   There was a point early on, where making the runtime faster was often pretty easy, but  as time drags, the big impact gains are few and far between.     More often than not now, new gains are made not through changing the runtime, but tweaking the compiler to detect and gracefully replace particular 'dodgy' bits of logic or functions.   Another way gains can be made, is via tweaking the layout of the opcodes being produced based upon the most common circumstances users apply it, which is how the performance gains in the comparison opcodes are made above.

      Hopefully by now, you'll appreciate that Looping and decisions go hand in hand, so any performance we win back has a positive impact upon end user programs.   The comparison gains alone gave us some extra zip to our Repeat/Until  While/EndWhile loops, in one test making a While loop 4 milliseconds faster.    But the actual operation wasn't any different than in V1.64N and bellow.   But last night, i've been looking over the looping opcodes (again) for alternative methods of structuring the opcode data, trying to avoid fetching anything that may or may not be required.   It turns out, that  by pre-processing some the opcodes data, some work can be done at compile time, rather than an runtime.   With some interesting results..  

      Bellow we're looking yet another thrilling standard bench mark test between V1.64N and V1.64N2 Beta 4, the test is just timing a bunch of looping constructs from FOR/NEXT, REPEATS / WHILE and DECLOOP...same old same old..    So the V1.64N release can run the test and maintain a 48fps refresh, which is quickest of all of the classic versions of the PlayBASIC,  well... until now..    So running the same test through V1.64N2 beta 4 and we're able to maintain a 60fps rate.         Now we should point out that the real benefits of this test are recent changes are the conditional repeat/while statements.  There's perhaps a tiny gain in FOR/NEXT opcode, but nothing to write home about.    

      Comparing today's runtime performance using the standard test, against older editions we get a slight speed advantage,  where the V1.64N2 is running the FULL standard test in 3.7->3.8 seconds, about point 1->2 of a second quicker than V1.64N, which was one of the first editions to cross under the 4 second barrier.    For those who might not know, the standard test is a program that measures the performance of the all the common low level operations in the PlayBASIC runtime.  It was originally written way... back in 2004 and i've a collection of programs built from various Pb revisions across that time period.     It's interesting looking back on how long it takes those older versions, like the V1.089 revision takes almost 9 seconds to run same code.   It's kind of like looking back on fossils where you see large jumps in the performance to some structural change that was made.        

       Anyway,  we'll keep chipping away.. I think there might be a way to cache some structures accesses across expressions and perhaps groups of lines.. But we'll see.        
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: monkeybot on April 25, 2012, 04:36:47 PM
keep on chippin'
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on April 26, 2012, 12:05:55 AM

PlayBASIC V1.64N2  Beta #5 - Select / Case

     Some days you win some performance back, some days you lose some.  Yesterday was that latter,  was trying some rearrangements of the opcodes that handle  IF / THEN / IF ELSE ENDIF / SELECT statements.  Prior to making the changes,  based on the previous sessions results, I would happily bet that they'll be quicker also.. But.. nope, slower..   Spent most of the afternoon trying to get the win, but ended up reverting to the previous version.   Which happens.. an awful lot..     

     Not a complete loss though as the implementation of Select / Case statement has a number of fatty bits wrapped around the edges.  Surprisingly when brute forcing the Select/Case against IF/THEN blocks,  a raw IF/THEN was quicker over 25,000 calls of 10 options

     This type of decision block thing



     If A =0 Then DoSomething0
     If A =1 Then DoSomething1
     If A =2 Then DoSomething2
     If A =3 Then DoSomething3
     If A =4 Then DoSomething4
     If A =5 Then DoSomething5
     If A =6 Then DoSomething6
     If A =7 Then DoSomething7
     If A =8 Then DoSomething8
     If A =9 Then DoSomething9


vs


     Select A

           case 0 : DoSomething0
           case 1 : DoSomething1
           case 2 : DoSomething2
           case 3 : DoSomething3
           case 4 : DoSomething4
           case 5 : DoSomething5
           case 6 : DoSomething6
           case 7 : DoSomething7
           case 8 : DoSomething8
           case 9 : DoSomething9

    endselect


 
        In PB1.64N the test was showing a 2 millisecond bias towards the IF/THEN version.   Which can attributed to that opcodes precedence in the runtime.   In other words just calling one is faster than  the other, let alone what they actually do.   When looking through the select opode though there did seem to be a few places where the opcode could return earlier, so have plugged some leaks.  Which resulted in the two sides performing almost evenly.   Clearly the IF/THEN statement block above gives a FIXED execution time.  Where SELECT can exit the structure when a case is met.  The sooner that case is to the top the quicker. 

        So in the above example if you set A to 9, then they'd preform about the same, if A is 5, then the select block is approaching twice a quick and so on.   Now you can shuffle the  IF/THEN logic to  make the an almost identical logical structure, but it's a just a little extra work like bellow.



     If A =0 Then DoSomething0 : Goto Done
     If A =1 Then DoSomething1 : Goto Done
     If A =2 Then DoSomething2 : Goto Done
     If A =3 Then DoSomething3 : Goto Done
     If A =4 Then DoSomething4 : Goto Done
     If A =5 Then DoSomething5 : Goto Done
     If A =6 Then DoSomething6 : Goto Done
     If A =7 Then DoSomething7 : Goto Done
     If A =8 Then DoSomething8 : Goto Done
     If A =9 Then DoSomething9
Done:



     You can take type of tweak even further by moving to JUMP Table are per ON VARIABLE GOTO, but they don't suit every thing.    Ideally it'd be best if the compiler could recognized the most optimal implementation that best fits the case data.   But, unless your falling through this type of structure 1000's of times each frame, then it's not worth worrying about today.     

   

Type Caching

      Because ARRAYS are dynamic in BASIC, then every time you pull or write a data to an array,  the runtime has a bunch of overhead to chew through to just work out the location of said data in memory.    So the fetch cost is really a pretty significant drain upon performance, where the more accesses we have the more overhead we introduce.     So obviously caching values in Variables where possible is a better approach.   Variables are comparable to CPU registers in the VM.   Everything internally is biased toward them, given they're the currency of the instruction set.   

      One idea i've been mulling over for a while now would approximate some long term redundancy style  opt's you see in low level languages like C/C++,  which tend to solve accesses to a pointer and carry that pointer forward until it has to be recalculated.    Ideally if we pre-processed the source code, we could make a program reorder the user code into the more efficient sequences of instructions. 
   
      Ie.



  '      If we had some code like this

      Dim Table(100)

      For lp =0 to 100
             Table(lp)=Table(lp)+Table(lp)
      next

  ' could be this..

      Dim Table(100)

      For lp =0 to 100
             Temp=Table(lp)
             Table(lp)=Temp+Temp
      next




     Now you'll notice there's multiple accesses of the same cell in the array in the first snippet.   So an easy opt would be pull the value once in an variable , double it there and then write it back.     A pre/post processor pass could actually do this for us as it'd take a much broader view of the code, the compiler can't as it's not aware of how these accesses might stack up over time.  So any time there's a query, it drops the code to get/set the value from the array. 

    But,  what I think might possible would be introducing an alternative type of Get/SET process for subsequent accesses.  It wouldn't be as optimal as rearranging the expression tends to be, but I suspect it'd make a happy middle ground reducing the overhead of heavy structure accesses, effectly giving back some free speed for what minimal effect all round.


Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on April 27, 2012, 12:32:07 AM
 PlayBASIC V1.64N2  Beta #6 - Type Caching In math Short cuts

        Since yesterday I've been looking over how types are accessed,  this is a very old part of the vm instruction set and one where's not much room to move, so I've had to add some secondary lower priority instructions to help out with the caching.     Firstly, caching can only be applied to ordered accesses of the same typed structure.  So it can't pre-compute part the cell addresses of a number types  and hold them that for long periods of time, it's just the most recent access.    

        Starting simple, i've been testing the logic upon typed variable access inside the math short cuts operators rather than even attempting to let this run while on anything bigger.   Depending upon the operation and the target, the short cuts generally output much the same code as the unrolled expression, not always, but generally they do.   When used on arrays/types the code generator spits out  code that basically reads the array, does the math operations and drops the result back into the array.     Since the source and destination cells are known to be the same, we can short cut this by allowing the read as normal, then spiting out a cached write rather than a flow blown write.  

        Bellow we've some test code and results showing the proof of concept works.    The code just runs batches of additions on 3 fields in a type, 25,000 times.          


type Vector3D
x#,y#,z#
EndType

type Stuff

Name$
X
y
z#
Table(100)
V3 as Vector3D

EndType

Dim Me as stuff
Dim test(10) as stuff
Dim cool as stuff list

me = new stuff

Test(1) = new stuff


cool = new stuff

me.v3 =0  

max=25000

Do


cls
frames++

tests=0
t=timer()
for lp =0 to max
me.X+=1
me.y+=2
me.z+=3
next
tt1#+=timer()-t
print tt1#/frames
print Me.x
print Me.y
print Me.z
Me.x=0
Me.y=0
Me.z=0
tests++


t=timer()
for lp =0 to max
me.X=me.X+1
me.y=me.y+2
me.z=me.z+3
next
tt2#+=timer()-t
print tt2#/frames
print Me.x
print Me.y
print Me.z
Me.x=0
Me.y=0
Me.z=0
tests++


print "BandWidth:"+Str$(max*24*Tests)
print "FPS:"+Str$(fps())


Sync
loop




       
       Ok.. so result wise, running the first loop in V1.64N2 beta6 gives us something like a 20-25% boot in performance compared to V1.64N.    But there's a BUT..  Something that I'd not foreseen, is that when you cache subsequent accesses like this we can no long rely upon the PB's automatic on write type creation.  Simply because the write function has no idea where the cache data type comes from.

       What i mean is that in PB, when you write to types that don't exist, PB will allocate the type for you..


       Eg.
      Type Stuff
            Xpos,Ypos
      EndType

      ; declares the type, doesn't allocate the types structure, only the container
       Dim Me as Stuff

      ; So this is actually writing to a type that doesn't exist
       Me. Xpos = 45       ; writing to the type



      Since PlayBASIC knows the type of array/type your writing to, it allocs the structure for you.  Normally you'd do this with the NEW operator.  If you use lists, then that's the only way.    The thing is, if the code has to READ from the structure and then caches the read pointer,  in an expression like Me.Xpos++,  we're reading from a type that doesn't exist and caching this none existent structure, so when we run the cached write, BOOM it crashes.    

      So what this means is that if we enable caching universally across our programs we'll be a slightly changing the behavior of the runtime, even though it's fairly subtle difference, this could be the difference between some programs running and other programs not running without significant modification.    In particular, if you rely upon the automatic allocation.  If you don't, then there's no problem.    
       
      Been testing a bunch of examples, and at this point have only found one or two where there's any issue,  even so,  I'm not too comfortable setting caching as the default behavior as yet without a lot of 3rd party testing.   I suspect the best way forward will be like when the first editions of the expression optimizer appeared, where originally you had to enable it, then eventually  it became the default mode.  

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on April 27, 2012, 09:14:28 AM
Kevin, do you planning add new operators in new version?
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on April 27, 2012, 11:42:20 AM

Nope, only things planned are what's listed [plink]here (http://www.underwaredesign.com/forums/index.php?topic=3777.msg25342#msg25342)[/plink]

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on April 27, 2012, 11:52:54 AM
PlayBASIC V1.64N2 BETA #6 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY)

     PlayBASIC V1.64 N2  Beta #6,  this revision contains all the latest runtime optimizations and Language files..  

     The V1.64N revision 2 is meant to address a few issues found in the V1.64N upgrade, so far it's been more of an optimization based upgrade with various improvements being made to the PB VM.    The main changes found in this beta would be the new Compare operators, some conditional looping changes (repeat / Until  - While / EndWhile),  improved select case and last but not least Type Caching in the Math Operators.    

     Type caching is a method where the runtime can preserve info about type accesses across an expression.  So far, it's implementation is limited to only being available within short cut math operators such as ++, --, +=, -=, *=, /*  and logic operations.    

     Ie.

     Type Stuff
           X,Y,Z
     EndType
     DIm Me as Stuff
     Me = New Stuff
 
    ; the runtime can now remove some of the work from this type of operation
     Me.X++

    ;  It can't currently help if you do this
     Me.x = Me.x +1


      Internal tests show that caching gives us about around 25% gain in speed over the long hand version.   Be aware though, if you try and do this on types that don't exist you'll get a runtime error.   To create a type within the container, we use the NEW operator as shown above.  

      I hope, caching can be rolled out language wide, but my gut feeling is that we'll struggle to get enough people testing it across their code, which will mean it's implementation will be abandoned.  



Download


     Old Link removed


Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on April 27, 2012, 12:53:36 PM
great! i going testing some code! ^__^
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: OldNESJunkie on April 27, 2012, 06:15:20 PM
To quote Kevin: "I hope, caching can be rolled out language wide, but my gut feeling is that we'll struggle to get enough people testing it across their code, which will mean it's implementation will be abandoned."

Personally I say make it that way anyways especially if the performance gains are that large. People can adjust their projects if need be. d/l now to test myself.
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on April 27, 2012, 06:41:29 PM
i think work well, i tested my codes and some(~50) standard "Examples codes".
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on April 28, 2012, 12:40:01 AM
QuotePersonally I say make it that way anyways especially if the performance gains are that large. People can adjust their projects if need be. d/l now to test myself

  Have already been testing ways to expand this project wide, but unfortunately it's not turning out to be as simple as i'd hoped.  It can work nicely on serialized sequences of code, but issues frequently appear in blocks where there's a mixture of data structures being accessed.    The issue isn't that people would have to reshuffle their code to take best advantage (that's a given), the issue is that their code just won't work in some situations.   Finding those circumstances takes time and lots and lots and lots of testing.  

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on April 29, 2012, 01:06:13 AM
 PlayBASIC V1.64N2  Beta #7 - The Knock on effect

     Work continues on the expanding the parser to be more 'type cache' aware.   Internal testing shows the proof of concept works, there's no disputing that.  The tricky part is that the parser has to detect situations where the previous cached data has become invalid.  Imagine we have a typed high score array called HighScores.    Now if you manually insert new values into the high score table,  we often see a section of code loops from the end to the insertion point that reads the cell above and writes to the cell bellow.      
 
      A bit like this,


   
     For copylp=ArraySize to InsertPosition step -1
             HighScore(Copylp+1).Score = HighScore(Copylp).Score
     next


   
      Whats surprising about this very simple routine, is that it's one where the caching could easily break the run time execution.   Since the left expression  queries HighScore(Copylp) caching that access point,  but the write occurs on cell CopyLP+1 in the same array.   The parser can detect that different patterns and output a standard write to array in side expression.

      But, here's where it gets rather interesting..   Now lets imagine a situation where we're reading some data from a typed array,  but this time we're manipulating the index between multiple accesses across lines.
 

   
          print Array(Index).Value
          Index ++

          print Array(index).Value



    And bingo, this won't work.   The parser detects the pattern of each type access, but in both print expressions the accesses have the same pattern.   But clearly the code is not wanting to access the same type between prints, in this case, it's successive types in the structure..  Even though the situation is fairly bogus, it reveals something a hidden complexity when caching array accesses across multiple expressions.    Where  the parameter variables might have been altered since the previous access, making a any previous cached result invalid.  

   While the above situation can indeed be handled, it's far from unique.   So rather than even trying to run this project wide, the next objective is to sure up the caching across self contained expressions first, as seen in the first Highscore example above.   Pretty much spent all Saturday working through the logic of said change.   Previously, I'd mainly been testing linked typed variables, where user code tends to be set out in the fairly sequential manner, which creates more potentials caching  opportunities.     Implementing the cache isn't a lot of code, it's all about tweaking up the logic, so what's generated is valid VM code and equal to what would normally be generated.  

   Now as with all things parser you can get some knock on effects when making even tiny changes.  In PlayBASIC, the parser and code generation occur at the some time.  During an expression the parser does all the grunt work stepping though the user code, where it calls operation generator to spit out the VM code as it goes.  In long expressions we often need to store temp results, which end up in temp registers.    Interestingly, as by product of adding type caching, the parser can better detect when operations occur between temp registers.     Meaning we use less temp data, resulting in better memory fetching and less locals in user defined functions.    

   What does this mean, it means some free function calling speed for a completely unrelated topic.   Bellow we see a results of running the test code (bellow) in V1.64N and V1.64N2 Beta7.   Which give us a few free FPS back for absolutely nothing.  



Tests=10000

Do
cls 0

inc frames

// ===================================
// USer Functions VS Projected Subroutines
// ===================================

// ==========
// Test #1
// ==========

T=timer()
For LP=0 to Tests
result=SomeFunctionCalc(10,lp)
next
tt1#=tt1#+(timer()-t)
Print "Test #1 Average Time:"+Str$(tt1#/frames)


// ==========
// Test #2
// ==========

T=timer()
// Call the Psub function
For LP=0 to Tests
result=SomesubCalc(10,lp)
next
tt2#=tt2#+(timer()-t)
Print "Test #2 Average Time:"+Str$(tt2#/frames)





// ==========
// Test #3
// ==========

T=timer()
For LP=0 to Tests
result=SomeFunctionCalc(10,lp)
next
tt3#=tt3#+(timer()-t)
Print "Test #3 Average Time:"+Str$(tt3#/frames)



// ==========
// Test #4
// ==========

T=timer()
// Call the Psub function
For LP=0 to Tests
result=SomesubCalc(10,lp)
next
tt4#=tt4#+(timer()-t)
Print "Test #4 Average Time:"+Str$(tt4#/frames)


print ""
print "Fps:"+Str$(fps())


Sync

loop


Function SomeFunctionCalc(A,B)
    A=A*B
EndFunction  A

Psub SomeSubCalc(A,B)
    A=A*B
EndPsub A





PlayBASIC V1.64N2  Beta #7b - Cached Type Reading

      Type caching has been expanded activated across each expression, there's still a few gotchas but we're getting there.     Bellow (second pair of pictures) we're looking at the results of PB1.64N and PB1.64N2 Beta7b running the this snippet.    Allowing the parser to run through the expressions,  means that any code that's set out like   ME.X = ME.X  + 1 can now benefit from the caching also.   But really big winner in all this,  is when you access multiple dimension typed arrays.    If you look at the results the caching wins us back about 10 milliseconds from that part of the test..  Which i thing demostrates just how much work the runtime has to do read/write safely from an array.




type Vector3D
x#,y#,z#
EndType

type Stuff

Name$
X
y
z#
Table(100)
V3 as Vector3D

EndType

Dim Me as stuff
Dim test(10,10) as stuff
Dim cool as stuff list

me = new stuff


cool = new stuff

me.v3 =0 

max=25000

Do


cls
frames++

tests=0
t=timer()
for lp =0 to max
me.X+=1
me.y+=2
me.z+=3
next
tt1#+=timer()-t
print "Math Short Cuts on Typed Variable"
PrintTime(tt1#/frames)
print Me.x
print Me.y
print Me.z
Me.x=0
Me.y=0
Me.z=0
tests++


t=timer()
for lp =0 to max
me.X=me.X+1
me.y=me.y+2
me.z=me.z+3
next
tt2#+=timer()-t
print "Long Hand Math Operators on Typed Variable"
PrintTime(tt2#/frames)

print Me.x
print Me.y
print Me.z
Me.x=0
Me.y=0
Me.z=0
tests++


Index=6
Index2=5

test(Index,Index2)= New Stuff

t=timer()
for lp =0 to max
test(Index,Index2).x=test(Index,Index2).x+1
test(Index,Index2).y=test(Index,Index2).y+2
test(Index,Index2).z=test(Index,Index2).z+3
next
tt3#+=timer()-t
print "Long Hand Math Operators on 2D Typed Array"
PrintTime(tt3#/frames)
print test(Index,Index2).x
print test(Index,Index2).y
print test(Index,Index2).z


tests++

print "BandWidth:"+Str$(max*24*Tests*4)+" Bytes"
print "FPS:"+Str$(fps())


Sync
loop

Function PrintTime(T#)
ink $ffff0000
print "Time:"+Str$(t#)
ink -1   
EndFUnction


   



Just got this hooked up and are testing The second pair of picture



Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on April 30, 2012, 01:10:11 PM
PlayBASIC V1.64N2 BETA #7 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY)

     PlayBASIC V1.64 N2  Beta #7,  this revision includes the Type caching in the compiler / runtime.

     In the previous beta, types could only be cached within math short operations.  Which is a nice safe way to introduce the feature, but in this version the parser is able to cache type accesses across an entire expression.    This expansion means the compiler can now detect and simplify the following styles of expression for the run time.  Ie  Me.X = Me.X +1,  In fact, if you stack multiple accesses within the one expression,  you can take further advantage of caching.   So if we had this   Me.X = Me.X +Me.Speed, the runtime will pull the ME type into the cache once, after which it's only accessing the cached version. So at least two of the ME accesses in that expression are cached.  Performance wise, the more dimensions you have, the better this works.  

     While the parser can cache within each expression, it doesn't support caching accesses across multiple expressions or lines of code.  The reason for this, is that once we do that, we're in a bit of mine field.  Because as mentioned above, there's any number of situations where an array index variable could be changed,  a list pointer moved, or just flow of code can break it.    But we'll see.



Download


     old beta deleted

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 01, 2012, 03:15:20 PM
 PlayBASIC V1.64N2  Beta #8 - Global Type Caching

     Moving on from the expression type caching of previous beta's,  we head into the wild unknown wilderness that is global type caching.   In beta 7, the caching is activated during assignments styled expressions and then turned off again, to avoid potential logical issues at runtime.   Most of the logical stuff is fairly predictable, where caching could result in potentially runtime errors, it's the unforeseen stuff that worries me about this feature most of all.  As such, caching is disabled by default,  which reverts the parser to it's original behavior.   To enable it, we set Bit 1 in OptExpression,  Bit 0 is used to toggle the standard optimization (which is on by default), so to enable Both modes we set OptExpressions to an integer value of 3.

    Currently, i'm slowly picking through the parser tagging the various situations where the cache should be flushed or disallowed completely.   I'd like to say it's all working wonderfully well, but it isn't.  Small stuff seems to work ok, but the bigger apps virtually all die at this point.   Thus we'll focus on the small stuff for now :)  - Like for example the 'Cached Type Reading' bench mark from above.

    The post above, shows the results for PBV1,64N and V1,64N2 beta7 running the bench mark, now bellow we've got today's results.    At first glance you might not see the big deal, but beta 8 can run a complete forth test in the time  V1.64N can only run three of them.    Whats more interesting is that the forth test is benching 3D typed array accesses.     Now granted, the test code is set out to cache well, but I didn't think it'd work that well.  To put the test in terms of bandwidth, the demo is pushing around 1/2 a gigabyte of bandwidth per second, not too bad for a 10 year old runtime, on almost 7 year old hardware.  



PlayBASIC V1.64N2  Beta #8b - Write Caching

     Previously the cache state was only enabled after a READ access of the typed structure,  this has been expanded to support writes also.  Which wasn't a big deal performance wise, since generally if we're only writing to a type we're probably initializing  it's fields prior to use in a create object/character styled function.   A few extra fetches in a routine that's not being called 1000's of times isn't going to kill us, but it adds extra bloat to the runtime code.  

     You can get a quick example of the style of routine i'm talking about from the 8Way Layered Star Field / Asteroids Style (http://www.underwaredesign.com/forums/index.php?topic=3837.0) example.    Where there's a function that creates the layers where it's virtually all writes to the initialize the structure.

     This bit,

[pbcode]
Function CreateLayer(Size,depth#)
      Index=GetFreeCell(Layers())
   
      Layers(iNdex)=new tLayer
      Layers(index).Size=Size   
      Layers(index).x=0   
      Layers(index).Y=0   
      Layers(index).Depth=depth#

      NumberOfDots=rndrange(50,100)
      Layers(index).Shape=Make_Randomized_Dot_Shape(NumberOfDots,Size)

EndFUnction

[/pbcode]

     So we're got a bunch of successive writes to the same type.  So obviously in this case it's caching the write to the second, third and so on writes.  But not all of them.  Expressions that include function calls flush the cache.   So on the shape creation line, the write to Layers(Index).Shape is an absolute write, rather than cached one.    We can rearrange the code though to make sure all successive writes are cached  by pre-computing the function call as a variable, then writing that later.  
 
     Like this,

[pbcode]
Function CreateLayer(Size,depth#)
      Index=GetFreeCell(Layers())

      NumberOfDots=rndrange(50,100)
          ThisShape=Make_Randomized_Dot_Shape(NumberOfDots,Size)

      Layers(iNdex)=new tLayer
      Layers(index).Size=Size   
      Layers(index).x=0   
      Layers(index).Y=0   
      Layers(index).Depth=depth#
      Layers(index).Shape=ThisShape

EndFUnction

[/pbcode]

     Both versions are logically the same, but the second one just lets the optimizer do a better job.

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 03, 2012, 04:05:31 AM
 PlayBASIC V1.64N2  Beta #8c - Vector Stacking

     As with all upgrades it's not all feature adding, there's an addition cycle --> testing --> repeat until done.  Have ironed out a number of type cache related issues, It's far from 100%, but most of the big programs I was having problems with, work again.  Which is good thing.  So now it's time to dive deeper  find those nitty gritty issues through usage.    Hence knocking up some tech demos.    

     One demo I've been messing around with is basically a 3d particle explosion.  We have a linked list of 10,000 points and are plotting each points path, which is clearly overkill, but it makes for  a good test bed for brute forcing the runtime.  But if we have 10,000 points and there's say 15 array accesses per point, then as much as caching helps out, it's not a silver bullet in this type of situation.

     So the pictures bellow are comparing two methods side by side, the first method is native PB version of the particle code (unopt'd), the second is using a type of vector stack.  Where the user defines  a list of operations to apply to a stack of vectors and then executes the list on demand.   While it's a little more work to set up,  the results speak for themselves, with the stack version of the particle routine being around 3 times faster.  

     
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on May 04, 2012, 01:32:21 PM
3 times faster ^__^ sounds good!
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 04, 2012, 02:22:06 PM

   yeah sometimes we win some, sometimes we lose some, but every gain is nice, no matter how big or small..   
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: monkeybot on May 06, 2012, 06:00:02 AM
nice!
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 06, 2012, 11:16:13 AM
  it works pretty well, but i'm sure for many, it's going to be a pretty abstract concept,  as described [plink]here (http://www.underwaredesign.com/forums/index.php?topic=3838.0)[/plink] .    


Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 07, 2012, 03:01:11 AM
   PlayBASIC V1.64N2  Beta #9 - Disassembler

      Work continued on the upgrade over the weekend, but with shift in focus geared more towards testing then anything else.    I guess the only new addition a simple parser to convert string based Vector Stack expressions into an operations list for the resolve stack function, making the process a lot easier.    Unlike the PB compiler, the vector stack operation lists can be processed at runtime.  Giving a bit of leeway in how an operation is solved.  

      Anyway, in terms of testing, my focus has been on trying to validate where and when the compiler is seeing cachable type operations.   For some reason some programs with heavy type usage, return little or no successful caches, even though the code is serialized.    After a lot of head scratching ended up coming to the conclusion that it'd be much easier to see exactly where and when it's failing if I could look a dis-assembly of byte code.     Much older versions of the PB had something similar built in, but was removed long ago.    Luckily i had most of the material just sitting around.

      The disassembler can currently decode about 50% of PB core instruction set (don't need all of it), in the initial version it just showed the opcode and parameter data,  so you don't get anything even reassembling PB code back.   But yesterday added some 'clean up' routines that try to reconstruct that type of the expression that created this opcode, making it a lot more BASIC looking and easier to follow the logic.   Some logic you could basically resource with a pretty high accuracy really, where as some bits, you can't as the information just doesn't exist or it requires multiple passes to try and guess the original logic.      

       The tool is currently working well enough for me to get an overview at just what the compiler is producing in various situations, and it's already revealing  some rather interesting results.  There seems to be the odd occasion where certain expressions generate extra MOVE operations, where they could be short cut.  The odd extra operation is no big deal in a code that's executed infrequently , but that weigh is magnified in brute force situations.

       Another oddity appears when initializing the function scope, where it seems to be writing some bogus data, dunno what's up with that.   Perhaps the best thing about it so far, is that it reveals a few situations where merging some common operations could be used to reduce the vm overhead further.   Some of which I think could be done a lot easier from a dedicated optimization pre-processing pass though, but well worth putting on the ideas board..  



  PlayBASIC V1.64N2  Beta #10 - Download

    Old beta deleted:

   remember.. Type caching has to be enabled in these versions.  To do so, add the line  OptExpressions 3  to the start of your program.

   
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 08, 2012, 12:42:23 PM
  PlayBASIC V1.64N2  Beta #10 - Inner Workings Of Type Caching

       Testing is going pretty well thus far, the more code I look over the dis-assembly outputs from, the more little potential tweaks appear.   I think most of the problems i've been having with caching relate to array indexes where the index has changed between accesses.   The parser isn't smart enough to trap those situations as yet.  As a whole, the compiler takes a pretty nervous approach to caching, which you can see when picking over the code it's producing for various blocks.  If i suss out the problem areas, then it should be able to be relaxed a bit more, which in turn will make further improvements.  

        The disassembler tool is working well, still LOTS of stuff it doesn't have a clue about, but for what i'm interested in (the core logic) it works well enough now.   So well, i've dressed it a little more since yesterday.   Now it allows us to see reconstructed BASIC styled versions of the instruction set.  Some stuff, there's no obvious BASIC translation, but it's a lot more readable and easier to browse now than it was before.     Attached to this post you can see an example routine with caching enabled (it's one of the example from earlier in this thread) .  The tool colours key lines to help pick out the key operations i'm interested in.   Not too pretty to look at, but a much easier form of validation stand point.      
         
         
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on May 08, 2012, 01:18:24 PM
disassembler tool looking pretty good ^__^
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: monkeybot on May 10, 2012, 02:19:21 AM
what does OptExpressions  do?  i seem to have missed that one.
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 10, 2012, 02:56:11 AM
  OptExpressions is a compile time switch, much like Explicit, which you can toggle it on and off anywhere you like (within reason :) ).  The switch controls the activity of a group of redundancy optimizations that the compiler can apply to expressions and move operations during code generation.    It's technical not a user command, since there's no reason to actually turn it off today.  So It's basically a legacy feature now only used when something breaks in code generation,  like the same string function assignment problems in V1.64M for example.

  Much like the Type Caching changes mentioned above,  originally the standard optimizer features were turned off by default in those releases.  Since it would help some programs, but completely break others,    It took some time before those issues were resolved,  which is what i'm expecting here.   Once the issues are all ironed out, the cache mode will be on by default.    

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 10, 2012, 10:01:30 AM
  PlayBASIC V1.64N2  Beta #11 - Tuning The Sprite / Map Instruction Sets

     Shifting focus from the 'compiler' back to the runtime instruction set for a few days, namely how the VM traps instructions with the aim of adding a few batching/structure read/write typed opcodes as well.    Today I've been through all the mapping and sprite libs trying to arrange them for efficiently.   The less VM overhead, the better basically,  as over time (9->10 years of it) things bloat out.   But with a little cut and paste, the updated lib's are performing better in brute force situations.      

    In this example, we're running three separate for/next loop through 10,000 sprites pulling /setting and moving the X / Y cords from each sprite, simulating what most game loops will do at one stage or another.  

   eg

[pbcode]

   Max=10000   
   Dim Spr(max)
   For lp =0 to max
         Spr(lp)=NewSprite(rnd(1000),rnd(1000),1)
   next   
   

   Do
      Cls
      
      Frames++

      t=timer()
      For lp =0 to Max
            spr=Spr(0)
            xpos=getspritex(spr)
            ypos=getspritey(spr)
      next
      tt1#+=Timer()-t


      t=timer()
      For lp =0 to Max
            spr=Spr(0)
            xpos=getspritex(spr)
            ypos=getspritey(spr)
            positionsprite spr,Xpos,Ypos
   
      next
      tt2#+=Timer()-t


      t=timer()
      For lp =0 to Max
            spr=Spr(0)
            movesprite spr,1,1
            
      next
      tt3#+=Timer()-t


      print "      Pull Positions:"+STR$(tt1#/frames)
      print "Pull + Set Positions:"+STR$(tt2#/frames)
      print "         Move Sprite:"+STR$(tt3#/frames)
      print "                 Fps:"+STR$(fps())
         
      Sync
   loop
[/pbcode]

        The tuning up of instruction set gives us some more free speed back (about 5 fps on the test system) for no real deep investment of time, so it's basically free performance gain.   But, we've got remember that this is a brute force test of 10,000 iterations.    Most PlayBASIC games would be lucky to have 25 active sprites on screen.   So obviously, such opt's will have less impact in every day situations.  Having said that, the streamlining has been applied across all the  SPRITE functions.  So if you have a lot of queries / function calls per sprite, you may well see some real world benefit even with small object counts.   You may not also, but  thems the breaks :)  

        The mapping commands have had much the same treatment, with about the same returns really, but slightly better. Some calls will be much quicker, others will be the same..  A lot of the collision functions had a lot of VM overhead in the caller, much of that has been trimmed away now, Flatten out the performance of all the calls in Map command set.    

         Another thing I've been experimenting with in the maps library, is way to batch pair/groups of calls.   The idea being, is that if program code is set out so there's two (or more lines) of the basically the same function call, the caller can sit and batch them, avoiding some set up work between operations.  In the test it seems to work ok actually.    Where there's a brute test peeking map tiles tens of thousands of times.  Todays test version of PB, runs the test about 20fps faster than V1.64N.   Hard to tell if it'd be worth rolling out.    

         Where I think it would help is when the user is calling built in functions to query the properties of a entity such as a sprite or map or something.  

          Eg.
            xpos=getspritex(spr)
            ypos=getspritey(spr)

          So if we have code like this,  the calls could be batched together, making the second call almost free of overhead, the more i think about it, this type of concept might well be better suited to the third generation of the runtime.    




  PlayBASIC V1.64N2  Beta #11 - Manually Reading Sprite Vertex

         So tonight sessions continues on from today's cleaning up the Sprite caller lib in the VM,  previously i'd only done the GetSprite styled functions, but have pretty much gone over the whole thing now.    To bench mark this we have the following snippet (you'll need the bubble pic to run), from 2004.   The original code runs as is,  but with some slight tweaks we can really get running even better in V1.64N revisions.   No great surprise there, since N is much quicker than the version of PB this example with originally written in.

        Anyway, the really interesting thing  is that we're seeing a tangible performance gain from V1.64N2.  Where It's running around 208 FPS in N2, compared to 185 ish in 1.64N.    Which equates to about a 5% gain.  So in sprite terms,  N2 can render about 5 more sprites and it's older brother at approximately the same speed.   So there's some benefit to be had.    

[pbcode]
; PROJECT : Get_A_Sprites_Vertex
; AUTHOR  : Underware Design
; CREATED : 8/13/2004
; EDITED  : 7/08/2005

   ; added to cache types
   optexpressions 3

   randomize 67


` +====================================================*
`               >> SPRITE Rotation/Scale Test <<
` +====================================================*

 ; convert default font #1 from a true type font to a bitmap version
   MakeBitmapFont 1,$ffffff,8

 ; load the bubble image

   LoadfxImage CurrentDir$()+"..\..\..\gfx\bubble_64x64.bmp",1
;   LoadImage CurrentDir$()+"gfx\bubble_64x64.bmp",1
;   PrepareFXImage 1


; get the Screen widht/height
   sw=GetScreenWidth()
   sh=GetScreenHeight()
   
; set starting number of    Bubbles
   BubblesN = 100

; Create the Bubble Type
   Type Bubble
      X#,y#,XSpeed#,YSpeed#,Angle#,RotSpeed#
   EndType


   // ===================================================================
   // Init Sprites, dim's an array sets a bunch of sprites read for use
  // ====================================================================

   Dim Bubbles(BubblesN) As Bubble
   For starsI=1 To BubblesN
      Bubbles(starsI).x = Rnd(sw)
      Bubbles(starsI).y = Rnd(sh)
      Bubbles(starsI).xspeed = Rnd(5)
      Bubbles(starsI).yspeed = Rnd(5)   
      Bubbles(starsI).angle = Rnd(360)
      INC speed#
      If speed#>10 Then speed#=1
      Bubbles(starsI).rotspeed = speed#

      CreateSprite starsI
      SpriteImage starsI,1
      SpriteTransparent starsI,1
      PositionSprite starsI,starsX,starxY
      SpriteDrawMode starsi,2
      SpriteHandle Starsi,(GetImageWidth(1)/-2),(GetImageHeight(1)/-2)
      RotateSprite Starsi,Bubbles(starsI).angle
      ScaleSprite StarsI,0.15+(Rnd(100.0)/100.0)      
   Next starsI
   


; Direct All Drawing to the screen (back buffer)
   RenderToScreen

; Start of DO/Loop
Do

    cls rgb(80,50,30)

    // =================================================================
    // Run Through and update all the sprites positions
    // =================================================================

   lockbuffer          
         For starsI=1 To BubblesN

            x#=Bubbles(starsI).x+Bubbles(starsI).xspeed
            Y#=Bubbles(starsI).y+Bubbles(starsI).Yspeed

            TurnSprite Starsi,Bubbles(starsI).rotspeed

         
            If X#<0 Or X#>sw
               Bubbles(starsI).xspeed=Bubbles(starsI).xspeed*-1
            EndIf
      
            If Y#<0 Or Y#>sh
                  Bubbles(starsI).yspeed=Bubbles(starsI).yspeed*-1
            EndIf

            PositionSprite Starsi,X#,Y#   
         
            ; Read the Sprites Vertex
            x1#=GetSpriteVertexx(Starsi,0)
            y1#=GetSpriteVertexy(Starsi,0)

            x2#=GetSpriteVertexx(Starsi,1)
            y2#=GetSpriteVertexy(Starsi,1)

            x3#=GetSpriteVertexx(Starsi,2)
            y3#=GetSpriteVertexy(Starsi,2)

            x4#=GetSpriteVertexx(Starsi,3)
            y4#=GetSpriteVertexy(Starsi,3)

            Line x1#,y1#,x2#,y2#
            Line x2#,y2#,x3#,y3#
            Line x3#,y3#,x4#,y4#
            Line x4#,y4#,x1#,y1#

            Bubbles(starsI).x=x#
            Bubbles(starsI).Y=y#
         Next starsI
   unlockbuffer
   
   
     DrawAllSprites
   
     Print "Manually Reading the Sprites Rotated Vertex"

   Sync
Loop

[/pbcode]      

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 11, 2012, 11:37:57 AM
 PlayBASIC V1.64N2  Beta #11c - Smoothing Out Type Caching

       Yesterdays Sprite/Map reshuffling passes ended up going a lot faster than i'd expected.  It's not a lot of hands on coding work, it's just one of those things that often leads to broken instructions if your not careful, of which there were a few, but it all went pretty smoothly for once.   Which leads me back for another round at type caching problem,  which thankfully I've had a few more ideas about since last pass.

        In previous versions, the type cache optimizer is intentionally set up to be rather over protective. So the moment it spots a user or built in function call within an expression, it turns caching off, regardless if the function/command damages the previous cached data or not.   To combat this ,the command tables now have computed safely flag.    The process is a bit like a shot gun really,  where any function/command that accepts passed arrays as a parameter, is set to being potentially unsafe, the rest are tagged as safe.    Now, yeah I know that just because a function is being passed an array it doesn't necessarily mean our cache data will be broken, but better safe than sorry.  

        Now that's ok for built in commands/functions,  but for user functions there's really no easy way to accurately guess if the function destroys our cache data or not, so those calls disable caching until after the call.    The reason this is such an issue is that we're caching a raw pointer to a previously known to exist thing, a type in this case.   If we allow caching across user functions, and that function alters a previously cached type pointer, then we're in for a world of hurt.  Best case scenario is it'll pop a runtime error, but I can't check at runtime where the cache data comes from.  So if it's been corrupted unknowingly then any following accesses might just end up reading/writing from the wrong structure of the same type, or some different structure completely, potentially resulting in a horrible death..   It's possible to solve, but way too much work for the return.

        Even so, what we're got now, is already able to chomp out slabs of bogus accesses from some of the bigger example programs, such as YAAC and THESIUS XIII (http://www.underwaredesign.com/forums/index.php?topic=1896.0) for example.  The tweaked optimizer spots around 100 caches in the YAAC  demo (Yet Another Asteroids Clone) (http://www.underwaredesign.com/forums/index.php?topic=3258.0) and almost 400 optimizers in the THESIUS demo,  making around a 5/6 K saving in the byte code alone.  Saving a few K is not a big deal, its just that's 5K  less memory accesses the runtime now doesn't have to do, in order to do the same thing.   So provided the opt's are in routines that are heavily used, we're gaining some more free performance.     The down side, is that the Thesius demo is is still a little crash happy when caching is enabled globally.  YAAC works fine, but its definitely not 100% at this time.
 
        Anyway, I've also been able to address the changing variable issue mentioned earlier, now it's just matter of tracking down those last few annoying issues.



  PlayBASIC V1.64N2  Beta #11c - Download

     Old beta deleted:

   remember.. Type caching has to be enabled in these versions.  To do so, add the line  OptExpressions 3  to the start of your program.

   
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 13, 2012, 03:18:33 PM
  PlayBASIC V1.64N2  Beta #12 - Caching Seems Stable

        The more code I test, the more stable ti all seems with issues generally only occurring due to by product of the runtime allowing the user to read from none existent type structures.    While not feature I'm a huge fan of, we're basically stuck with it today.   Dunno what that is ?,  well imagine we have an array of user defined types.   When we DIM the array we're creating the 'container' for the types to live within, but we're not actually creating individual types.  The individual Type structures aren't allocated until you either alloc one via NEW, or WRITE to the structure, which makes PB automatically allocate a type of the 'arrays type'.  

         Ie.
[pbcode]

          Type Stuff
                   Status
                   Name$
                   x,y
                   Score
          EndType

          Dim Things(100) as stuff

          ; Auto creation upon writing to a field
          Things(50).Status = true
          Things(50).Name$ = "Bill"

          ; or manual allocation
          Things(60) = NEW STUFF
          Things(60).Status = true
          Things(60).Name$ = "Jenny"

[/pbcode]

     So after running the two writes, we end up with two shiny new types within our array.   All the others are yet to allocated, ie empty.   Now the thing is, often when iterating through a Typed array, we might end up with a loop that looks something like this.

[pbcode]

   For lp =0 to 100
 
        if Things(lp).Status

          print Things(lp).Name$

        endif

   Next

[/pbcode]


     Here the VM is polling every cell in our things() array.  Now since only two of them exist, wouldn't this give illegal accesses ?, Yeah, it should.. But It was decided that the VM should ignore those illegal reads, rather than pop a runtime error on them.    Now given we're talking about decisions from some 10 or more years ago, it's a bit difficult to revert that today,  without breaking older programs.  

     The solution is simple, rather than access the field of the type, we should always query the cell of the type to see if it exists or not.  If it exists the cell will be another other than zero, if it's not, it'll be zero.

     Like This,
     
[pbcode]

   For lp =0 to 100

        ; query this cell, for any value that's NOT zero, when it's not zero it must exist    
        if Things(lp)

          print Things(lp).Name$

        endif

   Next

[/pbcode]
 
        This method is perfectly safe and is preferred structure of such loops today, but I don't think that was in the original editions.  So while a lot of modern code tests the existent of the structure prior to using it, other routines don't.   This is not a big deal in a world without caching or when it's disabled, but caching  only work consistently when the run time knows for sure the thing that was last accessed, exists.   So the legacy behavior, is whats making caching a little shakey on older programs.    

        Tried a version of the Vm tonight that doesn't allow reading from none existent types, but as expected,  an awful lot of legacy programs don't work.  So,  what I think i'll end up doing is just leaving the existing behavior in classic versions of PlayBASIC, and implement it in PBFX runtimes.   It'd less of a culture shock that way...  



Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 14, 2012, 10:41:14 AM
  PlayBASIC V1.64N2  Beta #12b - Mmmmm Caching :)

       After soooooo looooong...... tinkering with compiler/runtimes, there's not much in the PlayBASIC world that actually surprises me.  Often a lot of work goes into the smallest of changes,  sometimes we win some handy double digit performance back or expand something to make it that little more flexible, but such changes are generally pretty marginal.   So imagine the look on my face tonight by simply re-blocking the cache instructions in the runtime, wins us back more performance that i'd even hoped for.    So much I was initially assuming it was broken..  Couldn't possibly be down in the low teens.. But it is.

       The test I'm using is the same basic type bench mark as always (Shown back here (http://www.underwaredesign.com/forums/index.php?topic=3833.0) ) The test just goes through and does a bunch of read/writes to a 1D/2D/3D types arrays.  Where each test is performed  25,000 times.   Now in previous versions of V1.64N2, caching has shaved from between 17% up to a staggering 30% of the V1.64N speed.    Which I was more than happy with to be honest.   But today's edition of  V1.64N2 beta 12b,  is  conservatively between 15-20% faster again.    The 3D array is basically twice as fast.

       Now even though the bench mark code is basically presenting a perfect situation for the optimizer to chew through the expressions, it'll certainly be able to improve the performance of your real world programs also.   Since  type usage is frequently serialized in programs, so if you have a loop that runs through and processes your game characters each frame (list or array) and there's multiple lines where the same structure is accessed (read /write), then those operations may  be anywhere from 25% to 50% faster..    The amount of time won back, really comes down to how frequently the loop is executed.  

       Attached we have the results from the test running on V1.64N, V1.64N2 Beta11 and V1.64N2 beta12b..   Speaks for itself really..  
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on May 14, 2012, 12:10:12 PM
this is really Great! ^__^
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: monkeybot on May 14, 2012, 02:17:13 PM
cool!
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 15, 2012, 10:23:21 PM
  PlayBASIC V1.64N2  Beta #12d - Download

       Well, here's todays build for you mess around with.  Pretty much completed Type Caching support and have dropped in some limited ARRAY Caching support.  Works ok, but given how arrays are normally used, there's unlikely to be a universal benefits.    

       I think we're pretty close to a release with this version,  there's still a few ideas floating around in my head for helper commands though.   Mainly just stuff to perform batched queries really.   Like reading the bounding volume (rect) from a sprite.   Which can then be drawn over a map level for selective refreshing styled render loops.   Just little things really.


 Download

       Old file removed
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on May 16, 2012, 02:18:52 AM
something wrong with my tetris code. (PlayBASIC V1.64N2  Beta #12d)

http://www.underwaredesign.com/forums/index.php?topic=3832.0
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 16, 2012, 02:48:23 AM

I don't think it's beta 12 related, as it doesn't work in 11 either..
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on May 16, 2012, 03:04:01 AM
i don't test code in 11 =)
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: OldNESJunkie on May 16, 2012, 09:23:56 PM
Well, I have to say that so far I LIKEY
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 17, 2012, 08:53:17 PM
  PlayBASIC V1.64N2  Beta #13a - Wrapping it up

       Was looking over the map library thinking about implementing some sprite to map masking function(s), but you can do much the same thing already.   I've added one new command though GetSpriteRect() which is a function to pull the bounding volume from a sprite after rotation and scaling.   Previously you'd have to query each vertex and then workout the rect from the vertex.   This can be very useful if you want to selectively refresh the backdrop, reducing the cost per pixel.  

       Selective refreshing in video games isn't a new concept,  it dates back to the dawn of game programming really.  8/16bit systems are notoriously slow, most weren't even quick enough to refresh a full frame of bitmap graphics at a playable rate, in particular when the scene contains overdraw.   You'd think that modern machines would be fast enough, but far from it.     Conceptually all we're trying to do, it minimize the number of the times each pixel that gets displayed is actually being drawn.   Pixels that are drawn over more than once,  are  costing us runtime performance.    

        If we imagine the standard FX buffer based refresh loop.  We'd have a FX formatted image the size of the display area, and we're making a Space Invaders game,  then the loop probably Clears the full screen buffer,  moves the aliens then renders them to the fx buffer.  If the screen is 800*600 and each alien is 32*32 pixels and there's say 100 of them on screen.    We can work out that to draw each frame we're hitting buffer around (800*600)+(32*32*100) =   480000 +102400 = 582400 times.

         Now clearly  that's a lot of fixed overhead, given much of the backdrop is going to be blank.    So a better approach would be to remember the area where each alien was being draw over, then to blank this area prior to be next frame redraw, avoiding the full screen CLS.   This reduces the redraw cost down to  (32*32*100) * 2 = (102400 *2) = 204800 times, cutting the cost per refresh in half.    
         
         Such a method would work fines, bit if aliens are being drawn over each other, then we're clearing / redrawing sectors of the original frame potentially more than one.    One easy way around this,  is to tag the character positions to refresh map.  The map is just a grid of blocks that need to be redrawn then. So it doesn't matter if the sprites over lap, we're only refresh that area once.    This is basically the approach the example bellow uses.  
               
        The following example creates a scene with moving sprite 'blob' things (Press Space to create), it's actually a variation of an older demo (http://www.underwaredesign.com/forums/index.php?topic=2548.msg17251#msg17251), the main change is that this version uses PB map/Level functions.    

        The code requires Beta 13 to run 100% correctly,  since older versions have a clipping bug CopyLevel, so it doesn't quite work in those versions.  

[pbcode]

;*=-----------------------------------------------------------------------------=*   
;
;               >> Selective Map Update II (Dirty) Tile Map Refresh <<
;
;                               By Kevin Picone
;
;                          Built Using PlayBasic V1.64n2.  
;
;               Copyright 2012 by Kevin Picone All Rights Reserved.
;
;*=-----------------------------------------------------------------------------=*   
;                   www.PlayBasic.com   - www.UnderwareDesign.com
;*=-----------------------------------------------------------------------------=*   

   loadfont  "arial",1,16,0,8


   // -----------------------------------------------------------
   // Size the Map blocks we'll use.  
   // -----------------------------------------------------------
   constant TileWidth   =32
   constant TileHeight   =32

   // -----------------------------------------------------------
   // Make the Backdrop image.  This buffer is also used for the 'FX surface'
   // -----------------------------------------------------------
   BackDropFX =MakeBackdropImage()


   // -----------------------------------------------------------
   // Make a blob image to represent the sprites in the scene
   // -----------------------------------------------------------
   Blob= MakeBlobImage(64,64)

   // -----------------------------------------------------------
   // Define a type to simulate some characters in the scene.
   // -----------------------------------------------------------
   Type tAlien
         Img
         X#
         Y#
         speed#
         direction#
   EndType

   // ------------------------------------------------------
   // Dim a list called Character to hold the objects
   // ------------------------------------------------------
   Dim Character as TAlien list


   // ------------------------------------------------------
   // Set the clip zone of the object
   // ------------------------------------------------------
   clipSize=64
   ViewportX1=-clipSize
   ViewportX2=GetSCreenWidth()+clipSize
   ViewportY1=-clipSize
   ViewportY2=GetSCreenHeight()+clipSize
   

   // ------------------------------------------------------
   // MAKE MAP / LEVEL / BLOCKS from our backdrop picture
   // ------------------------------------------------------

      Map=NewMap(10)
   
      ThisIMage=BackDropFX
      IMageWidth   =GetIMageWidth(ThisIMage)
      IMageHeight   =GetIMageHeight(ThisIMage)

      TilesWide   =IMageWidth/TileWidth
      TilesHigh   =IMageHeight/TileHeight
      
      if (TilesWide*TileWidth)>ImageWidth then TilesWide++
      if (TilesHigh*TileHeight)>ImageHieght then TilesHigh++
   
      BlockCount=(TilesWide*TilesHigh)+1
   
      CreateMapGfx Map,TileWidth,TileHeight,BlockCount,rgb(0,0,0),2
   
      OriginalLevel=NewLevel(Map,TilesWide-1,TilesHigh-1)
   
      rendertoimage ThisImage

      // ----------------------------------
      // Build map representation of this image
      // ----------------------------------
      Index=1   
      For ylp=0 to TilesHigh-1
         For xlp=0 to TilesWide-1
               Xpos=xlp*TileWidth
               Ypos=ylp*TileHeight
               GetMapblk Map,Index,Xpos,Ypos
               PokeLEvelTile Map,OriginalLevel, Xlp,ylp,Index
               Index++
         next
      next   
   
   
   RefreshLevel   =NewLevel(Map,TilesWide-1,TilesHigh-1)

   pastelevel map,OriginalLevel,Map,RefreshLevel,0,0,0   
   
   LevelTransparent  Map,RefreshLevel,0
   
   
    Screen=NewIMage(GetScreenWidth(),GetScreenHeight(),2)

   ;*=-----------------------------------------------------------------------------=*   
   ;         >> Main Loop <<
   ;*=-----------------------------------------------------------------------------=*   
   Do

         // Add new charcter to scene if the space key is being pressed         
         if Spacekey()
               Character             = New tAlien
               Character.img          =Blob         
               Character.x          =rnd(GetScreenWidth())
               Character.Y            =rnd(GetScreenHeight())
               Character.Speed      =rndrange(1,5)
               Character.direction# =rnd(360)
         endif         


         // Process and render to the objects in the character list
         RenderToImage Screen
         

;         lockbuffer
            drawmap Map,RefreshLevel,0,0
;         unlockbuffer
         
         ; reset the mask level
         ClearLevel Map,RefreshLevel,0

      lockbuffer
      
         For each Character()

               Speed#=Character.speed#
               Angle#=Character.direction#
               x#=Character.x+Cosradius(angle#,speed#)
               y#=Character.Y+Sinradius(angle#,speed#)

               if pointinbox(x#,y#,ViewportX1,ViewportY1,ViewportX2,ViewportY2)=false
                     Character=null
                     continue
               endif

               ThisImage=Character.img
               drawimage ThisImage,x#,y#,true
               Character.x=x#
               Character.y=y#

               x1=floor(x#)
               y1=floor(y#)
               x2=x1+GetIMageWidth(ThisImage)
               y2=y1+GetIMageHeight(ThisImage)
   
               // Convert Pixels to Tile positions
               x1/=TileWidth
               y1/=TileHeight
               x2/=TileWidth
               y2/=TileHeight
               x2++
               Y2++
               CopyLevel   Map,OriginalLevel,x1,y1,x2,y2,Map,RefreshLevel,TilePad+x1,TilePad+y1
         Next
         unlockbuffer
         

         rendertoscreen

         // Draw the current state of the Backdrop to the SCREEN
            Drawimage Screen,0,0,false

         // Draw the tile size at the mouse pointer
            mx=mousex()
            my=mousey()
            x=(mx/tilewidth)*TileWidth
            y=(my/tileHeight)*TileHeight
            box x,y,x+tileWidth,Y+TileHeight,false
   
         
         // Draw the info to the screen for the viewer   
            text 0, 0,"Refresh %:"+CalcRefreshPercentage(Map,RefreshLevel)
            text 0,20,"Fps:"+str$(Fps())
         
                  
         Sync
   loop   





;*=-----------------------------------------------------------------------------=*   
;                        >> Calc ReFresh Percentage <<
;*=-----------------------------------------------------------------------------=*   
;
;  This function converts an image into the array of tiles representing this
; image.  Each cell in the array contains the image handle of that 'sector'
; of the original image.   This is used to refresh the image during refresh.
;
;*=-----------------------------------------------------------------------------=*   


Psub CalcRefreshPercentage(Map,Level)
      Count=0
      Width=GetLevelWidth(Map,Level)
      Height=GetLevelHeight(Map,Level)
      
      Total = (Width+1)*(Height+1)
      
      For ylp=0 to Height
         For xlp=0 to Width
               Tile=PeekLevelTile(Map,Level,xlp,ylp)
               Count+=Tile<>0
         next
      next            
      
      p#=float(Count)/Total
      
      s$=str$(p#*100   )   

EndPsub s$






;*=-----------------------------------------------------------------------------=*   
;                           >> Make Blob image <<
;*=-----------------------------------------------------------------------------=*   
;
;    This function makes a Blob (circle/ellipse) image with alpha channel, which
; is use to represent a hand drawn sprite in your game.    
;
;*=-----------------------------------------------------------------------------=*   


Function MakeBlobImage(width,height)

      oldsurface=getsurface()
      Thisimage=GetFreeImage()
      CreateFXImageEX ThisImage,Width,Height,32
      rendertoimage Thisimage
      radiusX=Width/2
      radiusY=Height/2

      lockbuffer
         ellipsec (width/2),(height/2),radiusX,radiusY,true,rgb(255,255,255)
      
      nullpixel=Point(0,0)
      for ylp=0 to height-1
         A=float(ylp)/height*255
         A=lsl32(a,24)
         for xlp=0 to width-1
               ThisPixel=Fastpoint(xlp,ylp) and $00ffffff
               if ThisPixel
                  FastDot xlp,ylp,ThisPixel or A
               endif
         next
      next
      unlockbuffer
      prepareAFXimage ThisImage
      rendertoimage oldsurface
EndFunction ThisImage



;*=-----------------------------------------------------------------------------=*   
;                           >> Make Backdrop image <<
;*=-----------------------------------------------------------------------------=*   
;
;   This function create a backdrop image.  It's a bit of mess, but it'll do for
; the sake of the demo.  In a real game you'd obviously load your own backdrop.
;*=-----------------------------------------------------------------------------=*   


Function MakeBackdropImage()

   // Make the backdrop
      sw=GetScreenWidth()
      sh=GetScreenHeight()
      backdrop=NewImage(sw,sh,2)
      rendertoimage backdrop
      c1=argb(255,0,0,100)      
      c2=argb(255,70,50,0)      
      c3=argb(255,0,200,0)      
      c4=argb(255,0,0,0)      
      ShadeBox 0,0,sw,sh,c1,c2,c3,c4   
      loadfont  "Arial",2,64,0
      
      setfont 2
      for lp=0 to 200
         ink rndrgb()| $ff000000
         CenterText rnd(sw),rnd(sh),"<>"
      next

      ink argb(255,55,55,55)
      x=sw/2
      y=sh*0.4
      CenterText x-2,y-2,"Game Backdrop Image"
      ink argb(255,255,255,255)
      CenterText x,y,"Game Backdrop Image"
      setfont 1   
      deletefont 2
      rendertoscreen

EndFunction BackDrop

[/pbcode]




PlayBASIC V1.64N2  Beta #13a - Download

Get [plink] PlayBASIC V1.64N2 BETA #13a (Retail Compiler Only Beta) (http://www.underwaredesign.com/forums/index.php?topic=1150.msg25454#msg25454) [/plink]  (Updated)



Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on May 18, 2012, 05:36:10 AM
after i run my code, in root my disk D: created file "ByteCode.VM2". it's normal?
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 18, 2012, 09:10:39 PM

  normal in my version.. Refreshed the package since it was missing language files also.   
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 22, 2012, 07:04:58 PM

PlayBASIC V1.64N2 BETA #15 (Release Candidate)

      PlayBASIC V1.64 N2  Beta #15,  this revision fixes the outstanding known bugs listed in the bug forum.    I'm expecting this to be this the release version.    Therefore,  users are strongly advised to test this version across as many of their projects as possible prior to the release!



Download


     Get  [plink] PlayBASIC V1.64 N2 Beta #15 (http://www.underwaredesign.com/forums/index.php?topic=1150.msg25498#msg25498)[/plink]


Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on May 23, 2012, 11:25:51 AM
i tested some codes, work well =]
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 26, 2012, 09:32:31 PM
  PlayBASIC V1.64N2  Beta #15b - Docs Are Fun

    As with all upgrade phases, there's the unavoidable doc phase.   Dropped a couple of afternoons in already,  mainly just picking through where pictures could benefit.  Got a few ideas, but have only really made some for the mapping tutorial at this point.    

    Found one issue in beta 15 where mixing array caching with types in an expression could break the runtime.  So if you have an expression  like,

    SomeArray(Index)= SomeArray(Index) + SomeTYpedArray.Field

    It'd happily die.   Turns out the runtime shares some data between normal and typed arrays, making it untenable.  Since the parser caches the SomeArray(index) access before SomeTypedArray access, the location would be corrupted.   It's fixed in beta 15B,  but if you find a program that dies, then may well be a cause

     If you find one, try rearranging the expression like so

       SomeArray(Index)=  SomeTYpedArray.Field +SomeArray(Index)




   


 
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on May 28, 2012, 02:52:08 AM
PlayBASIC V1.64N2 BETA #15b (Release Candidate #2)

      PlayBASIC V1.64 N2  Beta #15b,  this version fixes the array caching issue found in the previous betas.   As with beta 15,  I'm expecting this to be this the release version.    Therefore,  users are strongly advised to test this version across as many of their projects as possible prior to the release!



Download


     Get  [plink] PlayBASIC V1.64 N2 Beta #15b (http://www.underwaredesign.com/forums/index.php?topic=1150.msg25522#msg25522)[/plink]


Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on June 03, 2012, 12:37:34 AM

PlayBASIC V1.64N2 - Documentation

     Been slugging it out, making another a pass over sections of the documentation.    One of the things that's always bothered me, is the lack of picture content in the doc's,  so I've been trying to knock up some small animated gifs to give some type of visual representation of what the code is doing, or some tutorial is rambling on about.   Which is quite possibly turning out to be the most boring things I've ever done, given how long it's taking.   To make the gif's i'm just saving out runs of sequential bmp files from PB, then using VirtualDub to import and export each set as an animated gif.  Turns out to be pretty easy once you get going.     

     Looking over the doc's there's actually a number of tutorials in parts sitting in the database.  None of them are anywhere near complete, but the most useful one seems to be a sprites tutorial.   So the past couple of sessions I've been sitting down and having blast at that one.   Some of the stuff in it, we could probably ditch, but might as well leave it there for the time being as it's possibly a bit too low level in places.   The idea of the tutorial is cover as much ground as possible, but you can't cover everything.   

                 
Learning Edition Update

      The distance between the current learning edition (based on V1.64L) and the current work in progress V1.64N2 revisions has become a deep divide, since it's now over 2 years behind the current build.    A lot has been implemented/changed in PlayBASIC in that time.   So there's a very strong argument to be made that it's time to upgrade the Learning Edition of the package also,  but I'm somewhat undecided now is the right time.    Given that this directly impacts upon my rather limited time for working on PBFX.   The current thinking is to get the retail version of V1.64N2 out, then when it's time to upgrade PB again, build a new LE version prior to that.  So the LE version is always behind the release version.   


   

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on June 12, 2012, 03:06:55 PM

PlayBASIC V1.64N2 - Documentation Continues

    Dropped at some 50+ hours into the documentation pass already and i'm barely half way through the sprites tutorial..  Was really hoping to knock that over as i'm rapidly running out of time for all things PB.   The sprite tutorial is broken up into a stuff like an introduction, motion, animation, collision , high level management and few other bits, like a section on the rendering stagings in the sprite engine.   The latter will certainly help some people get a clearer idea of how the render engine processes pixels from the source image, through the modifier and out to the destination surface.

    Have been doing some tinkering with V1.64N2 Beta 15  and  found a few examples that no longer work that should. One that comes to mind drops a phantom 'array doesn't exist' after that arrays been passed around a bit.  Got a feeling some of the array functions might clash with the array cache.  But will have to crack it open to have a look see. 
     
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: Big C. on June 13, 2012, 12:03:25 PM
The sprite thing sounds interessting... Hope it makes somthing clearer to me ;D Maybe the series can user exspandble...
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on June 13, 2012, 01:26:08 PM
New Documentation, sounds interessting! ^__^
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on June 13, 2012, 01:46:02 PM

good to see people read the doc's.... erm :)
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: stevmjon on June 13, 2012, 06:49:16 PM
Quote from: kevin on June 12, 2012, 03:06:55 PM

     The sprite tutorial is broken up into a stuff like an introduction, motion, animation, collision , high level management and few other bits, like a section on the rendering stagings in the sprite engine.   The latter will certainly help some people get a clearer idea of how the render engine processes pixels from the source image, through the modifier and out to the destination surface. 
     


looking forward to it.
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on June 14, 2012, 02:02:47 PM

Quotelooking forward to it.

    Can't imagine there's anything all that new it, given it's paraphrasing what's on the boards..


Backups

     Taken a  day off all things documentation due to some sort flew like illness creeping in overnight, what fun...  Been trying to catch up on another round of backups though, but the burner has decided it's not going to behave and spit out some weird errors 50% of the time.   The discs seem to read other in other systems, but it's another bit hardware on it's last legs.    But anyway,  did happen to find bunch of old projects that I was looking for a while back,  there's even an old version of PlayANIM. 

     PlayANIM is the frame work of a basic sprite animation tool written some four or five years back.   After looking at it today (although briefly), the bare bones of something useful are there,  so it might be worth stripping the guts out it and using that core code with the newest 'standard' template for the GUI stuff.    To tool is split into two/three sections,  frame grabbing and animation building are the main ones.   Frame grabbing allows frame to be any size and in any order from any file in the pool.  I know there's version with animation sequencing, but this version doesn't seem to have that, no biggie.    Since that's missing stuff like real time changes to controlling the blending, Tint, Rotation, Scaling etc ) and some type of even parent->child  grouping would be handy. 

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on June 17, 2012, 12:31:08 PM
PlayBASIC V1.64N2 BETA #15c (Release Candidate #3)


      PlayBASIC V1.64 N2  Beta #15c,  this version corrects another potential issue from writing mismatched data into cached integer array accesses.    If nothing else is found, this all be the release version.

     Users are very strongly advised to test this version across as many of their projects as possible prior to the release as might be a while before it's updated again !



Download


    old file removed



Documentation

   Still ticking away at the doc's,  managed to save over one whole section of the sprites tutorial, without even noticing it until today.  Was going to throw that out, but remembered most of it, so threw another version together.   The sprites tutorial is about 90k of raw text,  making it around 3 times larger than any other tutorial in the doc's to date.   It's pretty example heavy though,  taking a progressive approach through the various subjects.  Most of the examples are variations of one running theme.

   Like this,

[pbcode]

  ; Force PlayBASIC to limit the program to
  ; a max of 60 frames per second    
   SetFps 60.0
   
   
   ;*=--------------------------------------------=*   
   ; Load Animation Frames
   ;*=--------------------------------------------=*   


      ; get playbasic compiler path to guess
 ; location of the help file media  

      path$=ProgramDir$()+"\Help\Commands\Media\Animations\Star\"

      for Count=1 to 8

         ; build this filename
         File$="Star"+Digits$(Count,4)+".bmp"               

         ; Load this frame into the required image slot
         LoadImage Path$+File$, 99 +Count

      next

   

   ;*=--------------------------------------------=*   
   ; Setup our  Game Character Type
   ;*=--------------------------------------------=*   


  ; Create Type called "GameCharacter"  
  Type GameCharacter

       ; declare XPOS and YPOS fields as integers      
       Xpos
       Ypos

      ; Declare Current animation frame as float
       CurrentFrame#

       ; add the anim speed field as float
       AnimSpeed#

  EndType


   ;*=--------------------------------------------=*   
   ; Init the our Star variable
   ;*=--------------------------------------------=*   



   ; Dimension STAR typed with LINK LIST Support
   Dim Star as GameCharacter LIST
   

  ; Set up a for / loop to count from 1 to 10
  For lp = 1 to 10
   
      ; Add a new Empty star to the list
      ; The new item is now the current item
      ; within star. So we're now accessing it
      ; every time we access star's fields  
        Star = New GameCharacter

      ;  set the Xpos and Ypos fields of current star
       Star.XPos  = rnd(800)
      Star.Ypos  = rnd(600)
   
      ; Set CurrentFrame to 100
      Star.CurrentFrame = 100

      ; Randomly pick our animation speed.  The rate'
      ; can be from as low as 5Fps and as high as 25fps
      Star.AnimSpeed    = RndRange#(5,25) / GetFps()

   next
      


   ;*=--------------------------------------------=*   
   ; MAIN LOOP OF PROGRAM
   ;*=--------------------------------------------=*   

      Do

         ; Clear the screen to black
         Cls


         ; Update all the Star Characters
         for each STAR()
         
             ; Add this characters anim speed to it's
             ; current frame and wrap the results
            Star.CurrentFrame#= WrapValue(Star.CurrentFrame#+Star.AnimSpeed#, 100, 107)
       
          ; Draw this image at it's current position and frame
           DrawImage floor(Star.CurrentFrame#), Star.Xpos, Star.Ypos,true

         next
         

         ; Show the newly drawn scene to the user
         Sync

      ; Check if the ESC key is press ?, if not,
      ; loop back to the DO statement until it is
   loop EscKey()=true

[/pbcode]


  It doesn't start at this level, this is about 2/3 of way through, so it pretty bare bones stuff.. LoadImage, DrawImage type stuff initially.   The sections put forward progressively ideas on how to make the initial examples better by using various techniques.   Like loading images in Loops for example,  using Floating Point CirrentFrame# counters with ranged wrapping.   So slowly the clunky versions morph into more flexible.   Can't possibly cover everything.. but enough to give some beginners a starting point.  You can find more complex usage examples both in the Projects Pack that ships with PlayBASIC and of course here on the forums.

  Anyway, have pretty much fleshed out the main sections now, but still got to write some more stuff on collision and a few more management examples.   Much of management section, relies upon the users knowledge of things like Types/ Arrays / Linked Lists..     Which thankfully we already have tutorials covering those.    

 
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on June 21, 2012, 10:28:52 AM
 Documentation Continues

   Yep, still hacking my way through the Sprite Tutorial.  Today, I'd be willing to say it's complete enough  so that somebody new to all this jazz could learn enough to make a bit of a basis.   It actually covers a lot fringe stuff also, from some history sprite,  double buffering, syncing.. etc...   but in some ways I guess it poses more questions than it answers for some people.   In that, where and when to you use sprites or manually render images ? - There's no black and white answer.   And the more laterally you think about it, you can create sprite like scenes from all kinds of materials in PlayBASIC.   Ranging from vector art,  texturing mapping stuff through to Bitmap fonts and even Maps all mashed into into one.    So the one solution fits all just doesn't stand up.

   Anyway,  going to tweak up the article a bit more and perhaps build a few more examples.  If that goes as planned, then i'll bumble up a release version and that'll be that.

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on July 20, 2012, 07:07:33 AM

PlayBASIC V1.64N2 -  Are we there yet ?

     It's been a pretty bizarre month for me, my plans  basically went out the window when some family issues (we'll call it that ) occurred.   Long story short, all things computer related had to take a back seat.   The upgrade hasn't stalled, it's not canceled and will indeed be released, as for exactly when I'm not too sure.  Was hoping this week, but that's unlikely today.   What I can say is that this week, i've had a lot more time for all things UW + PlayBASIC related.    So I've been pumping in some hours doing some 'clean up' work on the some common parts of the doc's.   Last night focusing on the Maths/Strings stuff which i suspect hasn't been looked at for some time now.     Most of the clean up stuff is about perhaps adding some more copy, another example better cross linking and the odd picture.    Still lots of stuff that bothers me about the doc's but i'll have to live with it. 

     My original goal was to have a clean up pass of the doc's for the V1.64N2 retail release, wait a while, then build a learning edition from V1.64N2.  By then we should have enough feedback to address any issues etc and repeat the process again.  Simply because we don't have enough active beta testers.   To build a learning edition  we'll need to a complete pass over the project packs and documentations.  So it's important as much of the information is up-to-date as possible..   One thing that never ceases to amaze me is just how long a complete documentation pass can take.   Was working out recently that i've spent almost a year of my life writing PlayBASIC documentation, scary.     

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on July 24, 2012, 02:15:48 PM
 PlayBASIC V1.64N2  Retail Released

  So the upgrade is finally built and uploaded.  Lots of new stuff all packed into this edition.  

 Download [plink]PlayBASIC V1.64N2 Upgrade (http://www.underwaredesign.com/forums/index.php?topic=1182.msg25774#msg25774)[/plink]
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on July 24, 2012, 03:35:46 PM
great work! new docs really impressive!
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: micky4fun on July 25, 2012, 11:10:48 AM
Looks like many examples and demo's for me to try here , how much fun can one have
thanks for all the hard work in keeping us all up to date,

great work !! ;D
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on August 24, 2012, 10:13:39 AM
  PlayBASIC V1.64N3 - Oh dear, another one

   While knocking up some more examples and bits and bobs for those active people on the forums,  it's not that uncommon to run into something behaving badly.  One such oddity has been the Block classification routines in the Map library.  The block classification is just some routines that scan block pixels and attempt to quantify the pixel data that's inside each block.  Preferable without stalling the entire process.

    The trouble has been, that certain pixel combinations can give return wrong answers.  Making the odd tile appear 'solid' when it's semi transparent. This is not a new thing, it's been acting strangely for a while, but locking down the cause isn't always as linear as i'd like.   Finally found the problems (i think!), which has turned out to be interesting in a boring programmer sort of way, where one issue was that a previous block state could carry forward breaking the decoder.  Which was an off shoot of the optimizations at the time.  Ya get that.  

    To test this, I've been using a level from Sigtrygg's  Hell Eagle game (http://www.underwaredesign.com/forums/index.php?topic=3869.0).  In that game, the world is made up of one large picture.   I've taken backdrop, run it through Play-Pic2Map (http://www.underwaredesign.com/forums/index.php?topic=3781.0) which spits out about 8 meg of block data at (32*32 block size), something like 80% smaller than of the original size.  All you do now  is load the blocks and level map into PB and render them.  

   Bellow is a picture of the Hell Eagle map rendering in debug mode (The lines around the blocks).  The text represents the classification of the each block, which now seems to be giving the expected results for the three primary block types.   -1 = blank , 0 = solid and  1 =transparent


The dream (nightmare) is over ? - New Beta

    Yep.. unfortunately what this all means, is we'll need to build another update at some point on the sooner side, rather than later side.

    Download [plink] PlayBASIC V1.64N3 Beta #1  (http://www.underwaredesign.com/forums/index.php?topic=1150.msg25933#msg25933) [/plink]



Hell Eagle Mock Up (Test Project)

       I'm using this  little side-project to put the mapping stuff through a real life usage, rather than smaller examples.   The only way to find issues hiding down deep in the guts of the library,  is by digging in and writing something.   It's mostly been fine so far,  the block classification changes seem to be working a lot of better now, at least in the limited range of testing I've been able to do tonight.    There's some stuff  that needs looking at, which is surprising given the age of the library now. The recent update was 2 years ago..

       Anyway, since the tech is about mapping and worlds thought i'd knock up a world loader.  It's just a text file.  The parser is just some cut'n'pasted loops,  but it gets the job done.    The loader pulls the text file in, cuts it up into an array of strings and just scan down it looking for the section names. When it finds one it calls a function that reads the particular fields of that type.   Not pretty, or that clever.. but it's quick to write and does the job.  Internally the demo does most of the work.  Like after parsing the sections of the characters are set up.  You could manually associate eat character with the platform it belong to, but it seems easier to just write a little routine that found the closet platform to the character.   We could use this in game as way the characters can query if the player has landed on the platform.   The same sort of idea would work when picking which character runs to the chopper... You could painstaking define all the orders, but seems easier just doing it with some code.   

       In this pic, the men are drawing lines to the center of the closest platform, the player has not logic behind it, it's just mouse controlled.   Using the SpriteHitMap function to detect the impacts.  But there's a bit of problem with that,  it's fine in some places, and not others.  I think there's a span buffer issue hidden away in that.  None of the less, shape mode seem to works fine.   Speed wise, it'll draw the 1024*768 frame in 5 millisecond refresh (200 fps) on a 7 year old system.   
 


; --------------------------------------------
; Hell Eagle Mock Up World Dizzy
; --------------------------------------------


Player-Section
StartingXpos =1420
StartingYpos =300

#


Map-Section
     BlockMaskColour   = $ffff00ff
     BlockWidth        = 32
     BlockHeight       = 32
     BlockFileName     = WORLD_Blocks.Bmp
     LevelFileName     = WORLD_Level.Map
#


Platform-Section

Width  = 110
Height = 4
Colour = $ffffffff

addplatform =206,452
addplatform =2726,412
addplatform =460,840
addplatform =2873,764
addplatform =276,1440
addplatform =1010,1575
addplatform =2289,1913
addplatform =197,1936
addplatform =2696,2303
addplatform =149,2303
addplatform =1481,2299
addplatform =3737,192
addplatform =3776,949
addplatform =3384,1849
addplatform =3566,2694
addplatform =3435,3057
addplatform =2044.3062
addplatform =1361,3008
addplatform =144,2994

#




Men-Section

addman =180.0 , 425.0
addman =320.0 , 424.0
addman =340.0 , 424.0
addman =2650.0 , 384.0
addman =2705.0 , 384.0
addman =2900.0 , 383.0
addman =2980.0 , 383.0
addman =428.0 , 814.0
addman =630.0 , 813.0
addman =2773.0 , 737.0
addman =2850.0 , 737.0
addman =3000.0 , 737.0
addman =258.0 , 1410.0
addman =385.0 , 1410.0
addman =1010.0 , 1543.0
addman =1102.0 , 1543.0
addman =2275.0 , 1883.0
addman =2440.0 , 1883.0
addman =2460.0 , 1883.0
addman =193.0 , 1905.0
addman =290.0 , 1905.0
addman =2670.0 , 2273.0
addman =2940.0 , 2273.0
addman =2970.0 , 2273.0
addman =2985.0 , 2273.0
addman =33.0 , 2274.0
addman =63.0 , 2274.0
addman =96.0 , 2274.0
addman =280.0 , 2274.0
addman =298.0 , 2274.0
addman =1380.0 , 2270.0
addman =1400.0 , 2270.0
addman =1600.0 , 2270.0
addman =1680.0 , 2269.0
addman =1720.0 , 2269.0
addman =3732.0 , 161.0
addman =3852.0 , 161.0
addman =3878.0 , 161.0
addman =3771.0 , 920.0
addman =3891.0 , 921.0
addman =3381.0 , 1818.0
addman =3476.0 , 1818.0
addman =3526.0 , 2665.0
addman =3546.0 , 2665.0
addman =3665.0 , 2665.0
addman =3417.0 , 3028.0
addman =3545.0 , 3028.0
addman =2000.0 , 3033.0
addman =2025.0 , 3033.0
addman =2155.0 , 3033.0
addman =2185.0 , 3033.0
addman =1335.0 , 2980.0
addman =1470.0 , 2980.0
addman =1493.0 , 2980.0
addman =140.0 , 2963.0
addman =240.0 , 2963.0

#



Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on August 26, 2012, 11:08:38 AM
  PlayBASIC V1.64N3 - Beta 2 - SpriteHitMap

     This weekend has become the sprite vs map collision challenge.  After a number of years away from those routines, they're not easiest thing in the world to pick up exactly how they work.   Although, 'works' would be an overstatement at this point.  It'll  happily detect some collisions with the map,  but apparently only when the sprite is within a certain zone of the map (top left corner).    When you leave that zone, the detection become irregular and ultimately the run time crashes.   So it seems that's a precision problem, which is leading to the crash (fetching outside of image memory).   But finding it is turning out to be more time consuming than I'd hoped.  


 It's Overflowing

       After another long exciting :) night of looking at the same sections of code over and over and over again,  it would seem the issue is indeed caused from an overflow.   It all comes down to the coordinates the scanner routine feeds to span buffer routines.   The span buffering uses 16:16 integer precision, which is pretty common in 32bit apps.   It means there's 16 bits whole part and 16 bits of fractional part.   We use 32 integers as it's quicker and more reliable than 32bit floats.   Anyway, when it goes to fetch a block, the span converter is using world space coordinate for the block, and since we've only got 16 bits of range,  this is being exceeded.   Haven't fixed it yet, but that's best evidence so far.    

         Bingo.. it's worrrrrkkkkkiiiinnnggggggg  (for now at least :))  


  Hell Eagle Mock Up

     Attached is the demo from the other day, I've commented out the sprite to map testing code, since i'm using this as my SpriteHitMap test bed.    
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: Sigtrygg on August 26, 2012, 02:55:23 PM
Hello Kevin!

Your work is great! I hope that you solve the problem with
spitehitmap. When I got the pink blocks in my map I thought
I had done something wrong. Now I know that there was an
other reason.
But the collision with the platforms works good with RectHitSpritePixels.
For me it is very useful to see how you manage the world.
I tried to render the map to an image and then tried to make a
sprite from that image. But it didn't work and I don't know if it
would bring an effect. Probably that is senseless?
In any rate thank you very much for your mock up!

Greetings

Sigtrygg
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on August 27, 2012, 01:35:17 PM
  PlayBASIC V1.64N3 - Beta 3 - Download

     Here's todays version of PlayBASIC V1.64N3,   this version has the newly tweaked SpriteHitMapPixels function in it.  End up pretty much replacing the core logic of the routine,  which was worth it, given that now it's working a lot more reliably.  Still a few gremlins in the machine,  namely when the sprites out side of the map area, which seems to give a few false positives here and there.   Not too sure why, hopefully it's just the clipping.      

     Now one thing that you'll need to be aware of (if you're not already), is the pixel level comparison routines expect the two images to be in the same pixel format.  Moreover, the collision routines assume the images mask colour is 24bit.   So if you load block data that uses a mask colour of $ffff00ff (A=255,R=255,G=0.B=255) and try and run sprite to collision with it today,  you'll  get hits on the mask colour as the collision routines apply a 24bit mask ($00ffffff) to the pass colour.    So if you have such a problem then RGB mask your image with $00ffffff to clear our the alpha bits if any  (RgbMaskIMage MyBlocks,$00ffffff.  


 Old Download removed



Sigtrygg ,

QuoteI tried to render the map to an image and then tried to make a sprite from that image. But it didn't work and I don't know if it would bring an effect. Probably that is senseless?

     In terms of doing pixel level impacts on maps between sprites, that's pretty much the original approach.   We'd work out the rectangle around the sprite, then draw this section of the map to a 'temp image' then compare it to the sprite (Search for ImageHitSpritePixels).   Other methods keep the tiles as separate images and which we than make sprites out of and compare the two sprites.    Or you can use vector etc etc

     In terms of displaying maps, if you're drawing AFX maps than you'll most likely be drawing to an off screen FX surface before drawing to the frame.  Although it can be handy to cache 256*256pixel chunks of onto Video images to create high performance scrolling environments.  All comes down to how creative one is about constructing the scene.      
   


 PlayBASIC V1.64N3 - Beta 3b - Using RayHitMapPixel for Line Of Sight

      After posting beta 3, i've been back tinking around the Hell Attack mock up.    Just want to include the basic game mechanics, using maps functions rather than other approaches.    The Game originally has all the main character types stored in separate structures, I've keep what I had previously the same, but have added a more generic structure now.   Where we have a basic game character structure, from which new character types are inherited.   Much like the Action GUI mock up the other day,  the game character has unique actions.  The core functions call these actions (if they) exist, making the interface more generic.   It's a little messy in places, but fairly expansible.  

       Anyway, bellow we're looking the game world again with the canons in place.   The Canons are active and will fire at the player given the right circumstances.  Those being within a certain range and when a timer has expired.   Those are met it'll fire toward you.   The thing is, it'd not have a clear shot.  So Here I figured would be a good real life usage of RayHitMapPixels.   This function can be used for line of sight between two points, if the ray hits the world the path is obstructed, if not it's clear.    Simple enough, we I tack the code in and nothing... Turned out to be issue with the function where it wouldn't  read the Level structure properly.  It's work for the level zero but nothing else..  Annoying, but easy fix..   The result can be seen bellow.   Where each canon is firing a ray rowards the player. If it hits the map, it draws a circle at point of impact, just for something to look at.  

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: Sigtrygg on August 27, 2012, 02:57:39 PM
Great!  :D
I don't really understand how you found the overflow, but
I have to try the new funtion SpriteHitMapPixels as soon as I can.

Greetings

Sigtrygg

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on August 28, 2012, 07:57:55 AM
  PlayBASIC V1.64N3 - Beta 3b

  Here's today's build, which includes more much needed corrections to the mapping library.  Which will be needed, in order to run the attached Hell Eagle Mock up correctly.


 Hell Eagle Mock

    Here's the latest version of the source code.  While the existing character types are managed individually,  I've added a generic layer to handle and remaining characters.    At this point, there's three classes of objects that fall under this category.  Canon, Canon Bullets and Explosions.     New characters just need to be named and inherited from the parent structure.  Characters have 4 or 5 set actions they might utilize.  Which are from memory CREATE, DELETE, AI, DRAW .

    So for each character type we add, we create functions in that character types name with the ACTION in the function name.  Therefore a character type "CANON"  can have CANON_CREATE()   CANON_DELETE()  , CANON_AI() functions.     When we call the generic functions, the interface will call the character action function if there's one defined.  

   Making our interface look at bit like this.  So with simple three function design, we can run pretty much run any character type in the game,  providing we stick to our simple naming convention.  

[pbcode]

Psub Init_Character(Index,Name$, Xpos, Ypos)

      ; set object to alive
      Objects(index).Status   =1
      Objects(index).x         =xpos
      Objects(index).y         =ypos
      Objects(index).ClassName=Name$

      F$=Name$+"_CREATE"
      if FunctionExist(f$)
            Objects(index).Actions.CREATE=FunctionIndex(f$)
      endif
      

      F$=Name$+"_AI"
      if FunctionExist(f$)
            Objects(index).Actions.AI=FunctionIndex(f$)
      endif


      F$=Name$+"_DRAW"
      if FunctionExist(f$)
            Objects(index).Actions.DRAW=FunctionIndex(f$)
      endif

      F$=Name$+"_DELETE"
      if FunctionExist(f$)
            Objects(index).Actions.Delete=FunctionIndex(f$)
      endif


      // --------------------------------------
      // Call custom creation function
      // --------------------------------------
      ptr=Objects(index).Actions.CREATE
      if ptr
            CallFunction Ptr,INDEX
      endif

EndPsub






psub Update_Characters()

   For lp=0 to GetArrayElements(Objects())
   
         if Objects(lp)
         
            select Objects(lp).status
            
                  ; -----------------------------------   
                  case 0       ; This Object is dead, so remove it
                  ; -----------------------------------   

                        Delete_Character(lp)

                  ; -----------------------------------   
                  case 1      ; Object is alive and kicking so call it's AI function (if it has one)
                  ; -----------------------------------   
                        ptr=Objects(lp).Actions.AI
                        if ptr
                              CallFunction Ptr,lp
                        endif




            endSelect
         
         endif
   next

EndpSub



;*=-----------------------------------------------------------------------------=*   
;*=-----------------------------------------------------------------------------=*   
;     *=--------------------[ DELETE CHARACTER ] --------------------------=*   
;*=-----------------------------------------------------------------------------=*   
;*=-----------------------------------------------------------------------------=*   


Psub Delete_Character(Index)

   if Objects(Index)

      Ptr=Objects(index).Actions.DELETE
      if Ptr
            CallFunction Ptr,INDEX
      endif

      Spr=Objects(index).Sprite
      if GetSpriteStatus(Spr)
            DeleteSprite Spr
      endif
      
      
      ThisAnim=Objects(index).Anim
      if GetAnimStatus(ThisANim)         
         DeleteAnim(ThisAnim)
      endif   

      ; free this structure
      Objects(Index)=Null

   endif

EndPsub


[/pbcode]

 
Movie:




Source Code Attached
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: Sigtrygg on August 29, 2012, 02:36:35 PM
Hello Kevin!

Thank you for the great mock-up!
It's for me a big opportunity to learn a lot!
The structure is absolutely clear, but I have to
spend much time for understandig the whole code.
Your idea to shoot the canonbullets with rays into
the direction of eagle is very good. At the moment
the bullets shoot in angles between 280° and 80°
randomly. If bullets are allways aim the eagle, you
have to be in movement all the time and of course
you have to shoot down the canons befor you
land onto the platforms. I would like to test this
out.

Greetings

Sigtrygg
I realize that it is now very comfortable to create
and integreate new levels for the game.
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on August 30, 2012, 10:44:00 AM
Sigtrygg,

Quote
The structure is absolutely clear, but I have to
spend much time for understanding the whole code.

  This is just conceptual frame work really,  rather than a blue print on how such things are done.   Generally when making programs, I tend to try and wrap up common 'operation' into functions (or psub's) to hide away the complexity.   The same goes for data, where common sets of variables get shoved into type structures.   Even, simple things like just using meaningful names, can go a long way to making programming easier.  it's might a bit of extra set up, but it pays off big time in the end.  

  The character handler in this demo is little different than one's i normally use in such demos.   It's more like the approach used in GUI's, but works just as well in game setting.  

   Related Examples

   * Abstraction Layer  (http://www.underwaredesign.com/forums/index.php?topic=3611.0)
   * Action GUI (http://www.underwaredesign.com/forums/index.php?topic=3899.0)
   * Entity Example (Loading Game Levels) (http://www.underwaredesign.com/forums/index.php?topic=3680.0)



Quote
Your idea to shoot the canonbullets with rays into
the direction of eagle is very good. At the moment
the bullets shoot in angles between 280° and 80°
randomly. If bullets are allways aim the eagle, you
have to be in movement all the time and of course
you have to shoot down the canons befor you
land onto the platforms. I would like to test this
out.

   Yeah, the canons in this demo don't behave the same as in your version.  To be honest, i'm not really trying to recreate your game, it's just been very handy to have having all the media and data sitting there, during the latest beta testing phase.   Normally i'd write a 'simple demo' when testing such things, but this is has been a lot more interesting.  

Quote
I realize that it is now very comfortable to create and integreate new levels for the game.

   That's good to hear, it's been a huge stumbling block for many over the years.  
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: Sigtrygg on August 30, 2012, 01:51:17 PM
QuoteNormally i'd write a 'simple demo' when testing such things, but this is has been a lot more interesting. 
And it is a great kind of lesson for us!
Today I analysed your code for handling the discription.txt
Once understand you can use it like a modul for future games, I think.
Or do you program every code part new, if you make a new game?
It is still hard to understand for me, how you use the types together with
the psubs, but I hope to get it soon  ;) Video on youtube is nice!!

Greetings

Sigtrygg
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on August 31, 2012, 12:58:42 AM
Quote
Once understand you can use it like a modul for future games, I think. Or do you program every code part new, if you make a new game?

 This particular loader would need to be customized for different projects. Some parts could be cut'pasted across to a new project though.   If you look closely you'll notice,  for each different data section,  I've just cut'n'pasted the same slab of code and altered the Select Case statements inside.  

 i.e. these blocks

[pbcode]

;*=-----------------------------------------------------------------------------=*   
;*=-----------------------------------------------------------------------------=*   
;*=-----------------------[ PARSE GAME CHARACTER SECTION ]----------------------------=*   
;*=-----------------------------------------------------------------------------=*   
;*=-----------------------------------------------------------------------------=*   

Psub Load_World_Parse_GAME_CHARACTER_Section(Row$(),StartingIndex)

      Dim Cords(10)
      For lp =StartingIndex to GetArrayElements(row$())
   
         s$=trim$(row$(lp))
         
         if len(s$)>0
            if s$="#" then exitfor

               Key$,Value$=Parse_Key_And_Value(s$)
            
               Select Upper$(Key$)
                  case "ADDCANON"
                     Count=SPlitToArray(Value$,",",Cords() )
                     Index = GetFreecell(Objects())
                     Objects(index) = New tCanon
                     Init_Character(Index,"CANON", Cords(0), Cords(1))
                                          
                     #print Key$

                  default
                        #Print "Unknown ->"+s$

               EndSelect
                  
            continue          
         endif
         
      next
      
endpsub lp

[/pbcode]

     I think with a little customization and a bit of creative thinking you could probably set up a 'fairly' generic library to use between different projects.    Although you could just use PlayUFF library.


Quote
It is still hard to understand for me, how you use the types together with the psubs, but I hope to get it soon

     Here i'm using the Types to collect related properties together.  So all the properties of the player, belong in the Players Type Structure, all the properties of the MEN belong in the men structure.     Once we've declared the Type, we can then create Variables/Arrays or Lists from that Type.  In a Typed Variable, we're got one variable (that can accessible project wide) that contains all of the fields of the Type.  

 
   
     In the mock up,  i've declared a type tPLayer to hold all the properties of the player.  It's Status, It's position, rotation angle and the sprite it'll use for it's on screen display.    Like so,

[pbcode]
   Type tPlayer
         Status
         Xpos#
         Ypos#
         Angle#   
         Sprite
   EndType

   // Set up the player state and create a sprite for it
   Dim Player as tPlayer

   Player = New tPlayer

   Player.Status = PlayerStatus_Alive
   Player.Sprite = NewSprite(0,0,   GameWorld.Image.Eagle)

[/pbcode]


     Now, we could create much the same functionality using separate  integer & float variables,  like this

[pbcode]
      Global  Player_Status
      Global  Player_Xpos#
      Global  Player_Ypos#
      Global  Player_Angle#
      Global  Player_Sprite  =NewSprite(0,0,   GameWorld.Image.Eagle)

[/pbcode]

      This can work just as well for individual characters like the player, but can be notoriously problematic as projects get larger.  Namely we're exposing ourselves to typo's,  it generally means we have to write every drop of code in that deals with the player uniquely.. Where as we can often reduce or share the various slabs of code between all the different characters type in game, using functions/psubs.    These are just a more modern take on sub routines, they both have slightly different behaviors (See the tutorial in the Help -> Under About -> Functions&Psub ) , i generally choose to use PSUB (Protected Subroutines), since I don't use recursion all that much, if ever actually and don't mind that local variables inside the sub aren't 'cleaned' on every call. Making them quicker at runtime.

      Anyway, we're getting way off topic.   I'll post the mock up in separate thread.  
     

      The latest version of the source code can be found Hell Eagle (Map / Level Mock Up) (http://www.underwaredesign.com/forums/index.php?topic=3914.0)




Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on August 31, 2012, 01:57:07 PM
  PlayBASIC V1.64N3 - Beta 5

     Tinkering around with a few tiny ideas tonight, one is a function to grab the vertical beam position from the video card.   The beam position is the current location (in screen scanlines) that the video card is pushing out to the monitor.  When we sync, we're either flipping the buffers in the video diver or coping to the back buffer to the front (in windows modes generally).  If we're copying a section of screen while it's being pushed we get tearing.    To avoid this we can wait for a top of frame.  However when we do this the driver sits in a busy loop, waiting for the beam to back in it's starting position.   This can make a  program chew a lot of cpu time just sitting around awaiting.  

     However, if we can read the scanline, it's possible to develop our own beam syncing.  To do this, we wait for the beam position to be beyond the bottom of our window.  Once there, we can sync without fear of tearing the moving frame. Moveover,  if the beam is positioned inside the 'window area', we can call the wait to give time back to the OS.  Making the app a little more system friendly than it otherwise would be.  Which could be handy for simple little programs.  

     The down side is not all video cards/driver support reading the beam position.   Can't do anything about that i'm afraid.   Here's a bit of an example.  

[pbcode]


// make a black/white pattern image as backdrop
      Dim Cols(1)
      Cols(0)=$304050
      Cols(1)=$80a080
      
      Size =32
      width=Size*8
      height=Size*8
      for ylp=0 to Height/Size
         for xlp=0 to Width/Size
            x1=xlp*size
            x2=x1+size
            y1=ylp*size
            y2=y1+size
            boxc x1,y1,x2,y2,true,cols( cell&1)
            inc cell
         next
      next
      GetImage 1,0,0,width,height



   Do
      cls
      
         tileimage 1,xpos,ypos,false


         Xpos=mod(xpos-2,Width)
         
         BottomScanLineY1=GetScreenYpos()+30
         BottomScanLineY1+=GetScreenHeight()
         bottomScanLineY1 = ClipRange( bottomScanLineY1,0,GetDeskTopHeight())
         bottomScanLineY2 = ClipRange( bottomScanLineY1+25,bottomScanLineY1,GetDeskTopHeight())
         
         repeat
            ScanLine=GetVBL()
            Dy=BottomScanLineY1-ScanLine
            if dy>0
                  Ticks=Cliprange(Dy/200,0,10)
                  if Ticks
                     Wait Ticks
                  endif               
            endif
         until (ScanLine=>BottomScanLineY1) and (ScanLine=<(BottomScanLineY2))
         Sync
   loop


[/pbcode]


Recasting Type Identifier

  The parameter parser will now auto recast type identifiers when passed into User defined functions (or psubs).     Which will be helpful in programs like the Abstraction Layer (http://www.underwaredesign.com/forums/index.php?topic=3611.0)

[pbcode]
   Type Dude
      Wobbley
   endtype

   Type Vertex
         x#,y#,z#
   EndType
   
   Yeah Vertex
   Test Vertex

   Sync
   WaitKey   


Function Yeah(ThisTypeIndex)
      print ThisTypeIndex
EndFunction

   
Psub Test(ThisTypeIndex)
      print ThisTypeIndex
EndPsub

[/pbcode]      



CallFunction Supports Pointer Parameters

   Added some pointer passing support to the CallFunction operation in the run time.   Being able to pass pointers in will be very helpful building function sets that are more generic object based.   Still can't return results, unfortunately that's due to byproduct of how the runtime works.    

[pbcode]

   Type Dude
      Wobbley
   endtype

   Type Vertex
         x#,y#,z#
   EndType
   
   Dim a(0) as Vertex
   a(0).x=100
   a(0).y=200
   a(0).z=300
   
   Dim Cool as Vertex Pointer
   Cool=New Vertex

   Cool.x=111
   Cool.y=112
   Cool.z=113
      


   callfunction "Test2",A(0).Vertex
   callfunction "Test2",Cool


   Sync
   WaitKey   


Function Test1(me as Vertex)
   if Int(me)
      print me.x
      print me.y
      print me.z
   else
      print "Failed"
   endif
EndFunction

   
Psub Test2(me as Vertex Pointer)
   if Int(Me)
      print me.x
      print me.y
      print me.z
   else
      print "Failed"   
   endif
EndPsub

[/pbcode]


  CallFunction includes some support for Passing Arrays()

    It's about bed time for me, but not without one final update.  Have continued messing around with the CallFunction parameter support and have got it handled passing Arrays() into Psubs ( no functions as yet)..   But it does indeed work,  so i'm  pretty happy with that.  


[pbcode]
   Dim Temp(5)
   
   callFunction "Test4",Temp()
   callFunction "Test4",Temp()
   
   Sync
   WaitKey   



Function Test3(Stuff())
   if GetArrayStatus(Stuff())
      for lp =0 to GetArrayElements(Stuff())
            STuff(lp)++
            print Stuff(lp)      
      next
   else
      print "Failed"
   endif
EndFunction

   
Psub Test4(Stuff())

   if GetArrayStatus(Stuff())
      for lp =0 to GetArrayElements(Stuff())
            STuff(lp)++
            print Stuff(lp)      
      next
   else
      print "Failed"
   endif
EndPsub

[/pbcode]






   



Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 01, 2012, 06:46:52 AM

PlayBASIC V1.64N3 - Beta 5 - Download



  Download   [plink]Download PlayBASIC V1.64N3 - Beta5  (http://www.underwaredesign.com/forums/index.php?topic=1150.msg25971#msg25971)[/plink]
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 05, 2012, 09:13:00 PM
  So am I to assume, every-bodies running the Beta5 without any issues then ?  Would like to wrap this all up pretty quickly that's all


Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: OldNESJunkie on September 05, 2012, 09:43:29 PM
Sorry Kevin, personally haven't had the time to test this beta out, had too much going on with family "things", I'll d/l it tonight, try it out with my project, let you know if anything crops up ???
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 12, 2012, 08:16:26 PM
 PlayBASIC V1.64N3 - Beta 6

      Back hacking away at the update this morning, noticed a problem with captured text a while ago and completely forgot  about until running into again.    So tracking down the cause of that has been focus this session.  Turned out the captured string length parameter was being padded from some completely unknown reason.  Can't help feeling a little nervous about such changes now, since there may well be some situation where that was indeed required...  Yeah.. what fun :)

[pbcode]

   loadfont "arial",1,32,0
   loadfont "arial",2,32,0,8   

   A$="Hello World"
      
   Cam=NewCamera()
      
   Do
         setcursor 0,0
         CaptureToScene
         ClsScene
         setfont 1
         print a$
         text 200,100,a$
         print str$(counter)         
         print str$(counter2)         
         

         setfont 2                  
         print a$
         text 200,300,a$
         print str$(counter)         
         print str$(counter2)         

         counter++
         drawcamera 1   
         Sync
   loop   
      
[/pbcode]


Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 16, 2012, 10:18:44 AM

Another Quick Documentation Pass

        Tonight's little chore is to give the Map collision commands another pass in the documentation, starting with RayHitMapPixels function.   Taking longer than I'd expected, but so do all things documentation.    Mostly been adding some stuff on possible uses, that sorta thing.     There's a few commands missing from the doc's for whatever reason, so those will have to added also.  Shouldn't be too much of a drama, just a big drain on the creative process.. :)

        The current time line for building the V1.64N3 upgrade is probably Tuesday (my time).   

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: micky4fun on September 16, 2012, 02:04:50 PM
PlayBASIC V1.64N3 - Beta 6

working fine for me

mick :)
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: OldNESJunkie on September 16, 2012, 02:44:04 PM
PlayBASIC V1.64N3 - Beta 6

working fine for me as well...
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: stevmjon on September 17, 2012, 05:24:28 AM
PlayBasic V1.64N3 beta 6

cool banana's.

stevmjon
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 18, 2012, 04:16:25 AM
 PlayBASIC V1.64N3 - Beta 7

      A new beta ? Yep, was right on the eve of releasing this update today (docs completed) when few issues have been spotted.  The main one apparently dates back to the Learning Edition (almost years ago), because all the subsequent versions I tested had the same drama, given the same situation.   Where the camera wasn't waiting fort the blitter to complete it's work before locking it, potentially killing the app.  Not good.    
 
      It just so happens to occurs in an example I was writing for the doc's,  where sometimes the circle would be 'flashy' (drawing while the blitter was drawing) or if you ran it full screen exclusive it'd generally die.    So would very much appreciate some feedback on if that's been solved in this beta from you guys also.   Just un-comment the OpenScreen statement.  


[pbcode]

   ;
  //   openScreen 800,600,32,2

;   -----------------------------------------------------
;           --------->> SET UP <<------------
;   -----------------------------------------------------


   Setfps 100


   ; Radius of test circle
   Radius=100


   ; create the random map from some circles
   Map,Level=Build_Random_Map(32,32)
   

   ; make a backdrop picture
   BackDrop=NewIMage(800,600)
   rendertoimage Backdrop   
      c1=rndrgb()
      c2=rndrgb()
      shadebox 0,0,800,600,c1,c1,c2,c2
   rendertoscreen   


   ; create a camera to view the scene with
   Cam=NewCamera()
   CameraCls Cam,Off

   

;   -----------------------------------------------------
;      --------->> MAIN LOOP OF PROGRAM <<------------
;   -----------------------------------------------------

   Do

      ; Get the camera current position
      CamX=getCameraX(cam)
      CamY=getCameraY(cam)
      
      ; Get the mouse position
      MX=MouseX()+CamX
      MY=MouseY()+CamY
      
               Method$="CircleHitMap"
         if Method=0
            ; Test if the Circle Hits the Map blocks
               Collision=CircleHitMap(Map,Level,MX,MY,RAdius)
         else
            ; Test if the Circle Hits the Map at pixel level
               Collision=CircleHitMapPixels(Map,Level,MX,MY,RAdius)
               Method$+="Pixels"
         endif


         if Collision
            Colour=$ff0000   
            Message$="Hit"
         else
            Colour=$0000ff
            Message$="Missed"
         endif


      ; tell PB to capture the following drawing commands
      CaptureToScene

      ; clear the scene buffer so it's empty
      ClsScene

      ; set the capture depth of the next item to a depth of
      ; 100 units   
      capturedepth 100      
      drawimage BackDrop,CamX,CamY,false
   
      
      ; draw the map level
      CaptureDEpth 10
      Drawmap map,Level,0,0


      ; draw the circle at this depth
      CaptureDEpth 20
      Circlec MX,MY,Radius,true,colour


      ; draw the scene with this camera
      drawcamera cam


      ; Check if the Space key was pressed
      if Spacekey()
         ; if so, change the collision method
         Method=1-Method
         flushkeys
      endif

      ; check if the ENTER key was pressed   
      if EnterKey()
         ; If so, toggle Debug mode on the map
         MapDebug Map,1-GetMapDebug(Map)
         flushkeys
      endif
         

         ; check if the users wanted to move the camera
         if LeftKey()  then   MoveCamera Cam,-2,0      
         if RightKey() then   MoveCamera Cam,2,0      
         if upKey()    then   MoveCamera Cam,0,-2      
         if downKey()  then   MoveCamera Cam,0,2      

         setcursor 0,0         
         ink $ffffff
         print "Press Space To Change Methods"
         print "Method:"+Method$
         print  Message$
      Sync
   loop


;   -----------------------------------------------------
;   ------------->> Build Random Map Scene <<------------
;   -----------------------------------------------------


Function Build_Random_Map(BlockWidth,BlockHeight)


 BackdropColour=$008f00

screen=newfximage(2400,1600)
rendertoimage screen
cls  BackdropColour
circlec 800,400,400,true,$8f8f8f
circlec 1700,400,400,true,$0f8faf

for lp=0 to 150
       x=rnd(2400)
       y=rnd(1600)
       rx=rndrange(50,150)
       ry=rndrange(10,50)
       ellipsec x,y,rx,ry,true, BackdropColour
next



Map=Newmap(50)

; Create 1024 FX BLocks for this map
createmapgfx  Map,BlockWidth,BlockHeight,1024,BackdropColour,2

BlocksX=GetSurfaceWidth()/BlockWidth
BlocksY=GetSurfaceHeight()/BlockWidth

Level=NewLevel(Map,BlocksX,BlocksY)
leveltransparent Map,Level,0
GetMapBlk Map,Tile,0,0
   
   Tile=1
   For ylp=0 to GetLevelHeight(map,level)-1
      Ypos=ylp*BlockHeight
      if Ypos+BlockHeight<=GetSurfaceHeight()
          For xlp=0 to GetLevelWidth(map,level)-1
             Xpos=xlp*BlockWidth
            GetMapBlk Map,Tile,Xpos,ypos
            
             if GetMapBlockTransparent(Map,Tile)>-1
               PokeLevelTile Map,Level,xlp,ylp,tile
                tile++   
            endif
            if Tile=>GetMapBlocks(Map) then exitfor ylp
          next
      endif
   next

   rendertoscreen

   ; Turn Debug Map for this map
   MapDebug Map,On

EndFunction Map,Level



[/pbcode]


Download

   obsolette file removed

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: stevmjon on September 18, 2012, 06:10:40 AM
PlayBasic v1.64N3 beta 6 : i couldn't see the mouse circle at all, in window mode or fullscreen mode (no crash in fullscreen).

PlayBasic v1.64N3 beta 7 : beautiful. all systems a go captain. i could see the mouse circle in both window and fullscreen mode, display was very smooth.

tested in windows 7 home premium.

stevmjon
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on September 18, 2012, 09:06:43 AM
PlayBASIC V1.64N3 - Beta 7 works fine.
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: stevmjon on September 18, 2012, 07:43:52 PM
PlayBasic v1.64N  :  could only partially see mouse circle with a flickering, in both fullscreen & window mode.

PlayBasic v1.64N3 beta 7  :  worked perfect, in both fullscreen & window mode.

tested in windows XP pro.

     stevmjon
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: OldNESJunkie on September 18, 2012, 10:05:49 PM
Seems to work here too, except I get an error if I don't change this line:

if Tile==GetMapBlocks(Map) then exitfor ylp

to this:

if Tile=GetMapBlocks(Map) then exitfor ylp

for some reason...
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 18, 2012, 10:22:43 PM
 that'd be because == isn't a supported operator.

It would appear PBCODE highlighter parses  "=>"  as "==" will fix that after.    (Fixed: PBCode parser updated 2012-09-18)

 
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 19, 2012, 06:44:28 AM

  PlayBASIC V1.64N3 - Beta 8

       Today (so far) has been all about optimizing.  As you've no doubt gathered i'm constantly trying to trim much  fat off the bones as I can, without breaking the bank.  Made some tweaks with the shape command sets again,  looking to improve the edge generation mainly, but have added a couple of special case render routines for drawing dots and lines.    Simple changes  that give a pretty sizable bang for your buck.   The changes help win about another say 10-25% (depending on the density of the shape) and more in some examples.     Seeing about a 50fps increase in the shape particle demo between today's build over V1.64N2...   But only about 15fps increase "Shape Particle Sprinkler"  (35000-36000 alpha adds points)


        Here's i'm just testing the span filling fill rate...

[pbcode]

   loadfont "arial",1,24

   max =500

;   ShapeQuantity Max*2

   For lp =1 to max
      CreateConvexShape lp,100,3+(lp and 7)
   next

   Do

      Cls

      frames++   

      t=timer()   
      xpos=0
      ypos=0
      lockbuffer
      For lp=1 to max
            ink rndrgb()
            offset=lp*2
            drawshape lp,xpos+offset,ypos+offset,2    
      next
      unlockbuffer
      tt#+=TImer()-t

   ink -1
   
   print tt#/frames
   
   Sync
loop



[/pbcode]




 
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 21, 2012, 01:46:30 AM
  PlayBASIC V1.64N3 - Beta 9 - Shape Tweaking

       Spent last night updating the Shape section of the help, which was pretty old.  Mainly just house keep stuff, cleaning the examples, adding a few pictures and more text etc.  Thrilling stuff.      In previous session I've been tackling shape filler routines, mostly getting some wins, but not always.  The filler is marginally quicker in today's build, but nothing you're likely to notice in everyday programs.   The brute force test ( the one posted above) runs about 4 milliseconds quicker.  Really a span clipper would run rings around that, but anyway.        

       While picking over the shape library (which is one of the oldest parts of PB)  noticed some legacy functions that are less than optimal as well as few that are no longer in use even.  So been fine tuning those bits over the last day or so.

        Result wise, it's pretty pleasing, the spacial partition demo from years and years ago which uses some asteroid looking shapes running about twice as quick (390 average fps) in today's build when compared back to V1.64L  upgrades (160 average fps).    There's not really any one change that makes the difference, it's more a bunch of often small changes over time.    

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 21, 2012, 09:31:11 AM
 PlayBASIC V1.64N3 - Beta 9

      I'm pretty much done with this now,  so here's what i'm hoping will be the final beta in this mini upgrade..  Give it run on your stuff and if there's nothing found in the next day or so, we'll package up the upgrade and upload it.



Download

   obsolete file removed


Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 22, 2012, 06:29:01 AM

  Ignore..  Just testing for the moment....


[pbcode]

   ; Inlude the Blit Image functions
   #include "BlitImage"

   
   ; Create an FX image the size of the screen

   Depth=32
   Width=800
   Height=600
   MyImage=NewfxImage(GetScreenWidth(),GetScreenHeight())
   CReateFXIMageEx MyIMage,Width,Height,Depth

   Screen=GetFreeIMage()
   CReateFXIMageEx Screen,Width,Height,Depth
   imageviewport screen,100,100,400,400   

   ; Start of Demo loop
   Do

      ; redirect all drawing to this image
      RenderToimage MyImage



      ; Set the Ink mode drawing pen to ALPHA 50 (50% blend)
      InkMode 1

      c2=-1
;      shadebox 0,0,width,height,c1,c1,c2,c2

      ; Set the Ink mode drawing pen to ALPHA 50 (50% blend)
      InkMode 1+32

      ; draw a circle at the mouses current position   
      Circle mousex(),Mousey(),100

      ; redirect all drawing to screen back buffer   
      rendertoimage Screen

      ; To do combined Blit (copy) our Image, with combined CLS of image.
      ; to the PB screen
      BlitImageClear(MyImage,0,0,rgb(30,50,100))   
   

      rendertoscreen
      drawimage Screen,0,0,false
      
      setcursor 0,0
      print GetImageDepth(Screen)
      
   
      ; Display Message
      print "Using BlitImageClear to draw MyImage with Clearing"
          
      ; flip the back buffer to the front, so the user can see it
      Sync
   
   loop


[/pbcode]
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 22, 2012, 01:04:30 PM
 PlayBASIC V1.64N3 - Beta 9b - Threading Test

   Just uploaded  PlayBASIC V1.64 N3  Beta #09b, this represents an experiment in threading.   Threads are a way to offload the execution of parts of your program from the main cpu and onto any other cores your system may have.   Thus sharing the load across the CPU cores in your computer, potentially resulting in better frames rate..  Meaning more action in your games.   We've fooled around with threading before, namely by attempting to split large blit jobs into swarms, which is slightly easier on the user, but very problematic to implement.    I've messed around with this a lot now and it would seem that just because the work load is shared, doesn't mean necessarily mean it'll would run quicker !

    Anyway, another solution is to attach threading into the BLITFX functions again, but this time treat each call as a JOB push.  So when we call a blit fx function, the request is passed off onto a secondary thread.   The render functions are customized so that once the job is pushed, we can then change surfaces and render something else while it's doing the bigger job in parallel.   This is easier to include in PB, but means you need to specifically write your code to take advantages of it.

     As for how well it works..  well i've no idea yet..  So get testing :)


Download

 [plink]Get Latest Beta (http://www.underwaredesign.com/forums/index.php?topic=1150.msg26099#msg26099)[/plink]



Threading Example

  This example, demo's asynchronous rendering.  At it's heart it's drawing a batch of circles, while it's copying the screen sized image to the PB screen.   We're using two separate FX screens here to avoid stalling.   If we only used one, it couldn't run them it parallel, as we'd be copying to the screen with altering the same image at potentially at the same time.  

[pbcode]

   #include "BlitIMage"

   Type tCircle
         x#,y#
         SpeedX#   
         Size
         Colour
   EndType

   
   Dim Object as tcircle   list
   
   For lp =0 to 500
         Object= New tCircle
         Object.x#   =rndrange(-800,1600)
         Object.SpeedX# =rndrange#(1,5)
         Object.y#   =rnd(600)
         Object.size   =rndrange(10,50)
         Object.Colour   =rndrgb() and $0f0f0f
   next   


   Dim Screens(1)

   ; CReate two FX buffers. We'll be doubling buffer the rendering
   Screens(0)=NewImage(800,600,2)
   Screens(1)=NewImage(800,600,2)

   FrontBUffer=0
   

   ; Enable Threading on BlitFX functions (At this point only BlitIMageClear is supported)   
   BlitFXThreadingMode 1

   
   
   do

      BackBUffer=1-FrontBUffer


      ; start the blitting the from buffer to the PB screen
      rendertoscreen
      
      ; Calling this function, pushes this rendering task onto a second thread
      ; when threading is ensabled.  So
      BlitIMageClear Screens(FrontBuffer),0,0,$304050       
      

      ; While the back ground thread is working drawing the Front Buffer image to
      ; the PB screen, we start drawing on to our  backbuffer   screen image.  
      ; Meaing it's doing two things at once, we're drawing circle, while it's BlitIMageClear'ing
      
      rendertoimage Screens(BackBuffer)
      
         Inkmode 1+64   
         For each Object()
               x#=Object.x+Object.SpeedX#
   
               circlec x#,Object.y,Object.Size,true,Object.Colour

               if x#>1600
                     x#=-800
               endif
               Object.x=x#
         next
         inkmode 1


      
      rendertoscreen

      ; Check if threaded blitting is enabled ?
      if GetBlitFXThreadingMode()
         WaitStates=0
      
         ; wait until the thread is complete         
         while GetBlitFXStatus()=1
            WaitStates++
            wait 1
         endwhile
      endif


      ; Press Space to toggle Threading
      if Spacekey()
               BlitFXThreadingMode 1-GetBlitFXThreadingMode()
               flushkeys
      endif

      Setcursor 0,0
      print "Threading:"+Str$(GetBlitFXThreadingMode())
      print "Wait States:"+Str$(WaitStates)
      print "Fps:"+str$(Fps())

      FRontBUffer=1-FrontBuffer         
      Sync
   loop

    [/pbcode]

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on September 22, 2012, 01:32:46 PM
In this example too much flash lines.
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 22, 2012, 01:34:57 PM

Quote
In this example too much flash lines.

what does that mean ?
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on September 22, 2012, 02:37:39 PM
i don't know how it work correct, but that lines changes very fast for 60 fps and more.
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 22, 2012, 11:21:02 PM

     Seems like there might be an overlap between when the Sync flips the pb screen pages and when the render thread is writing to the PB screens backbuffer.    Because the Sync is also asynchronous, as are more most 'video' memory operations.    If that's the cause, we'd need to force a wait condition so they're both not trying to render to/from the same memory. 

     One way might be force a lock surface, when before calling BlitImageClear.  The lock should, make it wait until all draw operations are complete. 

  Test #1

[pbcode]   

   #include "BlitIMage"

   Type tCircle
         x#,y#
         SpeedX#   
         Size
         Colour
   EndType

   
   Dim Object as tcircle   list
   
   For lp =0 to 500
         Object= New tCircle
         Object.x#   =rndrange(-800,1600)
         Object.SpeedX# =rndrange#(1,5)
         Object.y#   =rnd(600)
         Object.size   =rndrange(10,50)
         Object.Colour   =rndrgb() and $0f0f0f
   next   


   Dim Screens(1)

   ; CReate two FX buffers. We'll be doubling buffer the rendering
   Screens(0)=NewImage(800,600,2)
   Screens(1)=NewImage(800,600,2)

   FrontBUffer=0
   

   ; Enable Threading on BlitFX functions (At this point only BlitIMageClear is supported)   
   BlitFXThreadingMode 1

   
   
   do

      BackBUffer=1-FrontBUffer


      ; start the blitting the from buffer to the PB screen
      rendertoscreen
      
      ; Calling this function pushes this rendering task onto a second thread
      ; when threading is ensabled. 
      lockbuffer
         BlitIMageClear Screens(FrontBuffer),0,0,$304050       
      unlockbuffer
      

      ; While the back ground thread is working drawing the Front Buffer image to
      ; the PB screen, we start drawing on to our  backbuffer   screen image. 
      ; Meaning it's doing two things at once, we're drawing circle, while it's BlitIMageClear'ing
      
      rendertoimage Screens(BackBuffer)
      
         Inkmode 1+64   
         For each Object()
               x#=Object.x+Object.SpeedX#
   
               circlec x#,Object.y,Object.Size,true,Object.Colour

               if x#>1600
                     x#=-800
               endif
               Object.x=x#
         next
         inkmode 1
      
      rendertoscreen

      ; Check if threaded blitting is enabled ?
      if GetBlitFXThreadingMode()
         WaitStates=0
      
         ; wait until the thread is complete         
         while GetBlitFXStatus()=1
            WaitStates++
            wait 1
         endwhile
      endif


      ; Press Space to toggle Threading
      if Spacekey()
               BlitFXThreadingMode 1-GetBlitFXThreadingMode()
               flushkeys
      endif

      Setcursor 0,0
      print "Threading:"+Str$(GetBlitFXThreadingMode())
      print "Wait States:"+Str$(WaitStates)
      print "Fps:"+str$(Fps())

      FRontBUffer=1-FrontBuffer         
      Sync
   loop


[/pbcode]   


Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on September 23, 2012, 05:08:08 AM
that code works same.
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 23, 2012, 10:26:34 AM

  What you should be doing is trying to make it work on your end, but without feedback, this will be removed.


  This test saves two bitmaps to a folder on your computer (you set the folder/device), one show the state of the front and back buffer.  If they're not synced, it'll be read/writing to the same memory and hence the corruption.   

[pbcode]

   ; Insert your PATH/FOLDER TO SAVE TEMP PICTURES
   SavePath$="D:\"


  #include "BlitIMage"
  #include "SaveBitmap"


   Dim Screens(1)
   
   ; CReate two FX buffers. We'll be doubling buffer the rendering
   Screens(0)=NewImage(800,600,2)
   Screens(1)=NewImage(800,600,2)



   ; Enable Threading on BlitFX functions (At this point only BlitIMageClear is supported)   
   BlitFXThreadingMode 1


      ; start the blitting the from buffer to the PB screen
      rendertoimage Screens(0)
      cls 255
     
      ; Calling this function pushes this rendering task onto a second thread
      ; when threading is enabled. 
      lockbuffer
         BlitIMageClear Screens(1),0,0,$304050       
      unlockbuffer
     
      rendertoscreen

      ; Check if threaded blitting is enabled ?
      if GetBlitFXThreadingMode()
         WaitStates=0
     
         ; wait until the thread is complete         
         while GetBlitFXStatus()=1
            WaitStates++
            wait 1
         endwhile
      endif

      savebitmap SavePath$+"Picture0.bmp",Screens(0)
      savebitmap SavePath$+"Picture1.bmp",Screens(1)
      
      
      print "done"
      Sync
      waitkey

[/pbcode]


  Bellow is the expected result in both pictures.  (converted to PNG to save space on the board.. since the save raw BMP)
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 23, 2012, 01:15:26 PM
 PlayBASIC V1.64N3 - Beta 9c - Final Threading Test

     Uploaded  another beta with some threading tweaks called Beta #09c.   Works on the systems here, but I have my doubts we can get this into a universally useful state.




Threading Example

  This demo has a bunch of flags for you to tinker with, use them!   You really should be writing your own examples trying to help work out the particular conditions where such problems occurs within, as without some type of context I see little point continuing.  Can't fix what i can't see.


[pbcode]
   #include "BlitIMage"

   Type tCircle
         x#,y#
         SpeedX#   
         Size
         Colour
   EndType

   
   Dim Object as tcircle   list
   
   For lp =0 to 500
         Object= New tCircle
         Object.x#   =rndrange(-800,1600)
         Object.SpeedX# =rndrange#(1,5)
         Object.y#   =rnd(600)
         Object.size   =rndrange(10,50)
         Object.Colour   =rndrgb() and $0f0f0f
   next   


   Dim Screens(1)

   ; CReate two FX buffers. We'll be doubling buffer the rendering
   Screens(0)=NewImage(800,600,2)
   Screens(1)=NewImage(800,600,2)

   VideoBUffer=NewImage(800,600)
   JunkBUffer=NewImage(16,16)
   

   FrontBUffer=0


   renderscene=1
   

   ; Enable Threading on BlitFX functions (At this point only BlitIMageClear is supported)   
   BlitFXThreadingMode 1

   
   
      
   do



      ; start the blitting the from buffer to the PB screen
      rendertoimage VideoBuffer
      
      ; try to force a GPU wait
      GetImage JunkBUffer,0,0,16,16
      
      ; Calling this function pushes this rendering task onto a second thread
      ; when threading is ensabled.  
      lockbuffer
         BlitIMageClear Screens(FrontBuffer),0,0,$304050       
      unlockbuffer
      

      ; While the back ground thread is working drawing the Front Buffer image to
      ; the PB screen, we start drawing on to our  backbuffer   screen image.  
      ; Meaning it's doing two things at once, we're drawing circle, while it's BlitIMageClear'ing
      
      rendertoimage Screens(BackBuffer)

      
      if renderScene
         Inkmode 1+64   
         For each Object()
               x#=Object.x+Object.SpeedX#
   
               circlec x#,Object.y,Object.Size,true,Object.Colour

               if x#>1600
                     x#=-800
               endif
               Object.x=x#
         next
         inkmode 1
      endif
      
      
      ; Check if threaded blitting is enabled ?
      if GetBlitFXThreadingMode()
         WaitStates=0
         WaitOnBlitFX()
      endif

      rendertoscreen
      drawimage VideoBuffer,0,0,false


      ; Press Space to toggle Threading
      if Spacekey()
               BlitFXThreadingMode 1-GetBlitFXThreadingMode()
               flushkeys
      endif

      if Keystate(50)
            gfxmmx 1-Getgfxmmx()
            flushkeys
      endif

      if Keystate(19)
            renderscene=1-renderscene
            flushkeys
      endif

      Setcursor 0,0
      print GetBlitFXStatus()
      print "Threading:"+Str$(GetBlitFXThreadingMode())
      print "Wait States:"+Str$(WaitStates)
      print "Fps:"+str$(Fps())
      print "MMX:"+str$(GetGFXmmx())

      print FrontBuffer
      print BackBuffer

       for lp =0 to 50
         v=QueryAsync(lp)
         if V             
             print Str$(lp)+"="+Str$(v)
         endif
       next   


      FrontBUffer=1-FrontBuffer         
      BackBUffer=1-FrontBUffer

      Sync
   loop

   

    [/pbcode]

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on September 23, 2012, 02:15:58 PM
 PlayBASIC V1.64N3 - Beta 9c on this version code works nice =)
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 24, 2012, 01:23:52 AM

well, that's a start.   Although your video cards text rendering is terribly slow...  Add the line   MakeBitmapFont 1,-1,8 , and go back and try the previous examples. 

  Been starting on a couple laptops today, and it seems to work ok on one (but slower) and flickery on the other.. No idea why..

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on September 24, 2012, 02:19:18 AM
done
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 24, 2012, 02:27:42 AM

So it doesn't flicker when threaded ?  -  Although, I actually mean test the previous versions of demo.  Which is prolly back on the last page now. 

What CPU (exactly) is in it ?

The core 2 duo here flickers when MMX is enabled, it's fine without it.. I've a bad feeling they cheat in those chips.

 
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on September 24, 2012, 02:34:24 AM
No, i don't see any lines.
my cpu - AMD Phenom II x3 720
and this example's screenshots
[pbcode] #include "BlitIMage"

   Type tCircle
         x#,y#
         SpeedX#   
         Size
         Colour
   EndType

   
   Dim Object as tcircle   list
   
   For lp =0 to 500
         Object= New tCircle
         Object.x#   =rndrange(-800,1600)
         Object.SpeedX# =rndrange#(1,5)
         Object.y#   =rnd(600)
         Object.size   =rndrange(10,50)
         Object.Colour   =rndrgb() and $0f0f0f
   next   


   Dim Screens(1)

   ; CReate two FX buffers. We'll be doubling buffer the rendering
   Screens(0)=NewImage(800,600,2)
   Screens(1)=NewImage(800,600,2)

   FrontBUffer=0
   

   ; Enable Threading on BlitFX functions (At this point only BlitIMageClear is supported)   
   BlitFXThreadingMode 1

   
   
   do

      BackBUffer=1-FrontBUffer


      ; start the blitting the from buffer to the PB screen
      rendertoscreen
     
      ; Calling this function, pushes this rendering task onto a second thread
      ; when threading is ensabled.  So
      BlitIMageClear Screens(FrontBuffer),0,0,$304050       
     

      ; While the back ground thread is working drawing the Front Buffer image to
      ; the PB screen, we start drawing on to our  backbuffer   screen image. 
      ; Meaing it's doing two things at once, we're drawing circle, while it's BlitIMageClear'ing
     
      rendertoimage Screens(BackBuffer)
     
         Inkmode 1+64   
         For each Object()
               x#=Object.x+Object.SpeedX#
   
               circlec x#,Object.y,Object.Size,true,Object.Colour

               if x#>1600
                     x#=-800
               endif
               Object.x=x#
         next
         inkmode 1


     
      rendertoscreen

      ; Check if threaded blitting is enabled ?
      if GetBlitFXThreadingMode()
         WaitStates=0
     
         ; wait until the thread is complete         
         while GetBlitFXStatus()=1
            WaitStates++
            wait 1
         endwhile
      endif


      ; Press Space to toggle Threading
      if Spacekey()
               BlitFXThreadingMode 1-GetBlitFXThreadingMode()
               flushkeys
      endif

      Setcursor 0,0
      print "Threading:"+Str$(GetBlitFXThreadingMode())
      print "Wait States:"+Str$(WaitStates)
      print "Fps:"+str$(Fps())

      FRontBUffer=1-FrontBuffer         
      Sync
   loop[/pbcode]
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 24, 2012, 02:41:37 AM

  yeah, that won't work without changing the wait code, like this.

[pbcode]

#include "BlitIMage"

   Type tCircle
         x#,y#
         SpeedX#   
         Size
         Colour
   EndType

   
   Dim Object as tcircle   list
   
   For lp =0 to 500
         Object= New tCircle
         Object.x#   =rndrange(-800,1600)
         Object.SpeedX# =rndrange#(1,5)
         Object.y#   =rnd(600)
         Object.size   =rndrange(10,50)
         Object.Colour   =rndrgb() and $0f0f0f
   next   


   Dim Screens(1)

   ; CReate two FX buffers. We'll be doubling buffer the rendering
   Screens(0)=NewImage(800,600,2)
   Screens(1)=NewImage(800,600,2)

   FrontBUffer=0
   

   ; Enable Threading on BlitFX functions (At this point only BlitIMageClear is supported)   
   BlitFXThreadingMode 1

   
   
   do

      BackBUffer=1-FrontBUffer


      ; start the blitting the from buffer to the PB screen
      rendertoscreen
     
      ; Calling this function, pushes this rendering task onto a second thread
      ; when threading is ensabled.  So
      BlitIMageClear Screens(FrontBuffer),0,0,$304050       
     

      ; While the back ground thread is working drawing the Front Buffer image to
      ; the PB screen, we start drawing on to our  backbuffer   screen image. 
      ; Meaing it's doing two things at once, we're drawing circle, while it's BlitIMageClear'ing
     
      rendertoimage Screens(BackBuffer)
     
         Inkmode 1+64   
         For each Object()
               x#=Object.x+Object.SpeedX#
   
               circlec x#,Object.y,Object.Size,true,Object.Colour

               if x#>1600
                     x#=-800
               endif
               Object.x=x#
         next
         inkmode 1


     
      rendertoscreen

      ; Check if threaded blitting is enabled ?
      if GetBlitFXThreadingMode()
         WaitOnBlitFX()
      endif

      ; Press Space to toggle Threading
      if Spacekey()
               BlitFXThreadingMode 1-GetBlitFXThreadingMode()
               flushkeys
      endif

      Setcursor 0,0
      print "Threading:"+Str$(GetBlitFXThreadingMode())
      print "Wait States:"+Str$(WaitStates)
      print "Fps:"+str$(Fps())

      FRontBUffer=1-FrontBuffer         
      Sync
   loop

[/pbcode]
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on September 24, 2012, 02:46:59 AM
this code works nice 250-252 fps and not lines =]
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 24, 2012, 03:02:24 AM

whats the smiley for ?
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on September 24, 2012, 03:28:07 AM
 :) == =] == =)   ;D

I was mean that code is working.
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 24, 2012, 12:49:57 PM
 PlayBASIC V1.64N3 - Beta 9d - Working Threading ?

     After a day of banging my head on the keyboard I think we've got this working at a useful state.   The idea of adding this to the blitx fx functions is we can set up a parallel rendering/processing situation.  Where a secondary thread is doing a the FX screen copy on second cpu core, while our main program is doing something else.


 Current Commands (WIP)

      BlitFXThreadMode State         (1= Threading on,  0 = Threading Off immediate mode rendering)

      GetBlitFXThreadMode()       ; Get the current thread mode


      BlitFXThreadPriority  ThreadPriority    ;  Set the priority of this threading request.  Range between 1 to 15.   1 being lowest, 15 being highest (critical)

   ThreadPriority=GetBlitFXThreadPriority()   ; Get the current thread OS level thread priority that threaded rendering is using.  


   WaitOnBlitFX()           ; This thread waits until our drawing process is complete.  



 How Not To Use Threading

     Threading is only of any value, if you design your program to perform the task required in parallel with the main program.   Linear thinking and threading don't mix.

     For example , If I enable threading and call a blitfx function say BlitImageClear,  then this task is going to be offloaded from the primary program onto a second CPU core.  See bellow,

[pbcode]

      ; start the blitting the from buffer to the PB screen
      rendertoscreen
   
   
      ; When thread mode is enabled, this BlitFX function will be pushed onto a
      ; second thread.  
      
      BlitIMageClear Screens(FrontBuffer),0,0,$304050       
   
               ; wait until the other thread completes it;s task..         
                WaitOnBlitFX()


[/pbcode]


    Here we see a program that's gaining nothing from threading at all, why ?  The reason for this, is the the main program is being forced to sit and wait until the secondary rendering thread completes it's task.     What we should be doing, is getting the main program to perform some other no related task while the rendering takes place in the background.  And only wait for the blitx fx to complete when we actually need to use the result of that rendering.    

    In the main example bellow, we're starting the second thread doing the BlitImageClear, then rather than waiting for it complete, we're rendering our batch of circles to a secondary FX screen.    In a dual/quad core system the two tasks are being performed in unison.   Generally the blitFX function will finish long before main program is done drawing  the batch of circles, so we're not really gain much, other than offloading one screen copy onto the second core.




Download

    obsolette file removed

 

Threading Example

   Here's today update of the circles demo.   This time we're using the BlitImageAlphaPostMultColour function to copy the screen.   This function Copies the pixel then multiples the source pixel with the colour of your choice.   Standard depreciation effect.

   Function Keys = Number of Circles
   Esc               = Exit Demo
   D                  = Display Info
   M                  = MMX state
   Space             =Toggle Threading
   Left/Right Arrow = Change Thread Priority   (1 to 15)    


[pbcode]
   #include "BlitIMage"

   makebitmapfont 1,-1,8
   OptExpressions 3

   Type tCircle
         x#,y#
         SpeedX#   
         Size
         Colour
   EndType

   Dim Object as tcircle   list


   CircleCount=500   
   SpawnCircles(CircleCount)

   Dim Screens(1)

   ; CReate two FX buffers. We'll be doubling buffer the rendering
   Screens(0)=NewImage(800,600,2)
   Screens(1)=NewImage(800,600,2)

      
   FrontBUffer   =0
   BackBUffer   =1-FrontBuffer

   renderscene=1

   ; Enable Threading on BlitFX functions (At this point only BlitIMageClear is supported)   
   BlitFXThreadMode 1


   
   do

      ; start the blitting the from buffer to the PB screen
      rendertoscreen
   
   
      ; When thread mode is enabled, this BlitFX function will be push onto a
      ; second thread.   When it's turned off, the main cpu renders this here
      ; and now.  
      
      
   ;      BlitIMageClear Screens(FrontBuffer),0,0,$304050       
         BlitImageAlphaPostMultColour(Screens(FrontBuffer),0,0,$e0a090)
            

      ; While the back ground thread is working drawing the Front Buffer image to
      ; the PB screen, we start drawing on to our  backbuffer   screen image.  
      ; Meaning it's doing two things at once, we're drawing circles, while
      ; a second core is doing the BlitIMageClear'ing
      
      rendertoimage Screens(BackBuffer)
      
      if renderScene
         Inkmode 1+64   
         For each Object()
               x#=Object.x+Object.SpeedX#
               circlec x#,Object.y,Object.Size,true,Object.Colour
               
               if x#>1600 then x#=-800
               Object.x=x#
         next
         inkmode 1
      endif
      

      if scancode()<>0
      
         for lp=1 to 10
            if FunctionKeys(lp)
                  CircleCount=lp*500
                  SpawnCircles(CircleCount)         
            endif
         next
      
      
         if Leftkey()
            Count=GetBlitFXThreadPriority()-1
            if Count>0
                BlitFXThreadPriority Count
            endif      
         endif
         
         if Rightkey()
            Count=GetBlitFXThreadPriority()+1
            if Count<16
                BlitFXThreadPriority Count
            endif      
         endif
      
         ; Press Space to toggle Threading
         if Spacekey()
               BlitFXThreadMode 1-GetBlitFXThreadMode()
               flushkeys
         endif

         ; M = MMX toggle
         if Keystate(50)
            gfxmmx 1-Getgfxmmx()
            flushkeys
         endif

         ; R = Render scene
         if Keystate(19)
               renderscene=1-renderscene
            flushkeys
         endif

         ; D toggle the extra text details         
         if Keystate(32)
               Details=1-details
               flushkeys
         endif

      endif


      ; Check if threaded blitting is enabled ?
      if GetBlitFXThreadMode()
         WaitTime=Timer()   
         ; if it is, wait for the blit to complete
         WaitOnBlitFX()
         WaitTIme =timer()-WaitTIme
      endif


      Setcursor 0,0
      
      lockbuffer
      print "Threading:"+Str$(GetBlitFXThreadMode())
      print "Thread Priority:"+str$(GetBlitFXThreadPriority())
      print "Fps:"+str$(Fps())
      print "Status:"+Str$(GetBlitFXStatus())
      print "Wait Time:"+str$(WaitTIme)
      print "Object Count:"+str$(CircleCount)
      if Details=1

         print "MMX:"+str$(GetGFXmmx())

         print FrontBuffer
         print BackBuffer

          for lp =0 to 50
            v=QueryAsync(lp)
            if V             
                print Str$(lp)+"="+Str$(v)
            endif
          next   
      endif
      unlockbuffer
      
      FrontBUffer=1-FrontBuffer         
      BackBUffer=1-FrontBUffer

      Sync
   loop



Function SpawnCircles(Max)
   For each Object()
         Object = NUll
   next
   For lp =1 to Max
         Object= New tCircle
         Object.x#   =rndrange(-800,1600)
         Object.SpeedX# =rndrange#(1,5)
         Object.y#   =rnd(600)
         Object.size   =rndrange(10,50)
         Object.Colour   =rndrgb() and $0f0f0f
   next   

EndFunction



    [/pbcode]

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on September 24, 2012, 01:13:27 PM
i think all work very good  :D
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 26, 2012, 01:51:47 AM

PlayBASIC V1.64N3 - Beta 9e - Welcome to threading

      This version now supports a couple of different blitx FX rendering calls for those really adventurous PlayBASIC programmers out there.   The current system is singular job based solution.   Once all the fillers are converted, we'll look at adding stack/cache based creation also, perhaps even swarming mode, which will make it easier for those unable to wrap their minds around parallel programming.     However, that will no doubt mean some command names/parameter change etc.  So I'm not going to bother adding them to the doc's for this upgrade.    Will do that once the implementation has settled. 




Download

  [plink]Get Latest Beta (http://www.underwaredesign.com/forums/index.php?topic=1150.msg26099#msg26099)[/plink]



Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on September 28, 2012, 03:13:14 PM
 PlayBASIC V1.64N3 - Beta 9e - Blit Modes & Threading

   Today was the day i'd penciled in as release day,  but time has slipped by once again.   Currently about 1/2 way through making the blit fx functions threading safe.   It's a lot more code than you might think, those 5 or 6 functions are around 380K of  C/Assembly.    Making them thread safe just means going through and converting all the function interfaces to use local structures rather than global stuff.    Most of them are turning out to be easy, but as always, it's then you run into something that just refuses to work.   Which has been the story of this session.   While updating the Alpha Colour Addition  fillers, it turned out the 15bit version just didn't work.   It didn't crash, but the resulting image wasn't what i was expecting.   Given that it's pretty unusual format today, could have thrown it, was tempted after a while, but ended up rewriting it completely.  Works now and seems a tad quicker.

  I'm pretty tempted to add some image processing stuff and batching functions also.     You can currently light map a 2d game by using the BlitImageAlphaMultImage function.  This function takes two images and multiplies the RGB channels of every pixel together, writing out the resulting pixels.    So one image is the unlit picture/game/demo effect and those is light map.     If you've ever bothered to look through the example pack,  there's a few demos showing it's usage, or in Spooky Shadows (http://www.underwaredesign.com/forums/index.php?topic=3125.0).     Drawing the scene and light maps is fairly;y straight forward, but heavy in terms of rendering performance.  

  Threading should make effects like this a cake walk.    Basically the clever programmer would split the rendering process in half.   The main programs draws the game scene as normal,  but the lighting stuff is pushed off onto a thread.   So basically while we draw the game stuff, it's drawing the lighting stuff.    If we can queue up render items,  this should make drawing light maps virtually free on multi-core systems..

  The mind boggles.  :)

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on October 01, 2012, 02:18:27 AM

PlayBASIC V1.64N3 - Beta 10

      This beta rounds out the threading support for the BlitImage functions, so all the main functions can now be execute in the background.  We need users to test this as much as possible.  That doesn't mean running some example and saying yeah it works, that means writing your own examples.   You'll need to, if you want your games to support multi core systems.   

      To push a render task onto the secondary thread, just enable threading.. call the render function as normal.   When threading is ON (set to 1), the draw request is pushed from the main program to a second thread, which will start immediately in the background.   Some caution is needed, as we can't reliably draw to the same surface that the thread function is drawing to.   Because,  both our program thread and the background thread are running together.   If the background clears the screen say, while you draw a sprite to the same surface,  sometimes you'll see  a cleared background with a sprite in front, other times you'll see no sprite..  The latter could occur because we've not waited for the background to complete it's work.  So to get the best results you're going to have to structure your program accordingly 



Download

  [plink]Get Latest Beta (http://www.underwaredesign.com/forums/index.php?topic=1150.msg26194#msg26194)[/plink]



Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on October 02, 2012, 04:28:37 PM
  PlayBASIC V1.64N3 - Beta 11  - Cross Fading Images

      One of the things that I only just noticed that's missing from the BlitImage library of functions, was a variable alpha blending function.  Normally if you wanted to cross fade between two surfaces.   You'd alpha blend surface B onto A, then drawn A to the screen.   Which will work, but it's a destructive process.    There are times where you would want to draw a pair blended surfaces without altering them.

      The picture bellow is from a mutated version of the demo source (form an earlier post in this thread) where it's drawing a bunch of alpha additive circles to the buffer, depreciating the entire buffer using the Alpha Multiplication, which creates the blurring.   This  scene represents one surface, which is then being cross faded with a picture (just some old WIP piccy).   On my system (7 years old) the cross fade (with MMX enabled, single threaded) is about a 4 millisecond effect.    Newer systems will chew through much quicker.  But the point is that this process can be threaded.    So even it took 4 milliseconds on a dual core system, the job can pushed off onto the second core.  If the task can be interleaved behind other operations in our program,  it's becomes a free effect at runtime.

      The last few days i've been focusing entirely on the blit image functions.  Found a few well hidden issues in some fillers and have made a number tweaks. Since this is basically a rendering library,  it's about 50% assembly.    There's MMX versions of most of the fillers, but not all.  It's well worth adding, as they're generally twice as quick, but everything needs legacy fall back routines, making the process of adding a 'method' slow going.    The new alpha blender function (which only supports 32bit, 16bit + 15bit pixel formats) is actually 6 routines.  Don't think i'll bother a 24bit version, since none of the other blitimage functions seem to support it.  


 Swarming

       When threading was last on the radar, the approach was entirely based around using a swarm of threads spread across the host system to perform common tasks in unison. This allows the program to use as may threads as the programmer wants (within reason), meaning a computer problem can be broken up into small jobs and distributed across many CPU's at once.   Today we don't have this, the new implementation is queue based.  Where we push a job from our main program onto a secondary thread.    All these jobs run on a separate core to main program (if you have multi core system), but only on the one core.   There's advantages and disadvantages to both.

        Anyway you can share rendering of  blitImage functions between two cores, by first setting the Viewport of the destination surface, then call the render function.   This will push the job off to core #2,  core #1 will continue on.  Where we'd set the viewport to the other half of the screen and then call the same blit image function we wanted again.     So we're doing is splitting the job between the two cores.    So core 2 is drawing the top half of the screen and core 1 the bottom.      

     
[pbcode]
   #include "blitimage"
   



   Screen=NewImage(800,600,2)


   Do

         rendertoimage Screen
         inkmode 1+64
            circlec mousex(),mousey(),50,true, $304050

         inkmode 1                  


         rendertoscreen

         ; this first request is pushed onto core #2
         ScreenViewport 0,0,800,300
         ; turn blitimage threading on
         BlitFXThreadMode ON

         ; Calling this function pushes the task off onto core #2
         BlitImageAlphaPostMultColour(Screen,0,0,$e0a0b0)

         ; while Core#2 performs the blitimage function on the top half


         ; turn blitimage threading on
         BlitFXThreadMode OFF
         
         ; we now change the viewport to the lower half.. So core #1
         ;will render this now
         ; this first request is pushed onto core #2
         ScreenViewport 0,300,800,600
         BlitImageAlphaPostMultColour(Screen,0,0,$e0a0b0)

         ; restore the viewport
         ScreenViewport 0,0,800,600

         ; better wait for the core #2, it may not have complete it's job   
         WaitOnBlitFX()

         Sync
   loop

[/pbcode]


Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on October 04, 2012, 09:25:18 AM
Recursion And Self Modification Don't mix

    While 'testing'  beta 11,  thought i'd give the old chestnut of writing a limb based animation system quick try.   The concept is to create humanoid characters from set of linked limbs,  where the links act as joints.    While knocking a mock up together, ran into some of issues when rendering the limb set.  Since a set of limbs can link an unknown number of levels, using recursion (functions that call them selves) seems like an easy solution, and it is.    But wouldn't ya know it.. Ran the code, but only one list of limb appears.  

     Testing the loop and it theoretically works, so after putting on my detective hat,  It's here one of recent optimizations appears to come and bite us in the back side.    Modern revisions of V1.64N 2 and 3 use a self modification in certain looping structures (all 1.64 versions use some), these changes allow us to get rid of some dynamic fetching from the 'end' value in For/Next loops in particular.     This can cause issues with a for/next loop is inside a function that's calling itself from inside the loop.     While I think this situation is fixable without reverting back to the older implementation,  there does seem to be some iffy situations in regard to how recursive function sets up the new call.    

     Since writing the debugger a few months ago, back them it seem that the compiler was writing some bogus scope changing data for function calls.  Had a look and the code seems ok, but there's something not quite right with it somewhere..  Hopefully it's just some logic error, but tracking them down can be very frustrating, not too mention time consuming.  

     At the start of the week, my objective was to build the upgrade at the end of the week,  this is still the goal. Regardless so if the recursion issue can be ironed out in time or not.


  Test Code
         
[pbcode]

Function Search(LInk)
   print "Begin Searching:"+Str$(LInk)
   if (link<5) then Search(link+1)
   print "End Searching:"+Str$(LInk)
EndFunction

 Search(0)


sync
WaitNoKey
WaitKey

[/pbcode]


  Working in V1.64N3 Beta 12

[pbcode]


   Thing=0


Function Search(LInk)
   b#=link*15
   c#=b#
   #break
      
   print "Begin Searching:"+Str$(LInk)
   print "prior to call:"+Str$(b#)
   if (link<10)
       Search(link+1)
   endif
   
   print "after call:"+Str$(b#)
   print "End Searching:"+Str$(LInk)
EndFunction link


print Search(8)


sync
WaitNoKey
WaitKey


[/pbcode]



ignore, just a little test to see if if the scope table has all the expected locals in it.

[pbcode]

   zzz=45
   global Dude
   Dude=1222
   Cool(11)
   Cool(112)
   dd=34
   a=5



Function Cool(scale#)

      zzz=123
      local dude
      dude=45
       zz=45
   
      a=zzz*45
         
      global Sugar
      sugar=12234


      Dim Bill as  byte pointer

      aaa#++
      aabb$="a"

EndFunction


   print dude
   Print sugar
   print zzz
   
   sync
   WaitKey


[/pbcode]

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on October 05, 2012, 01:10:55 PM
 PlayBASIC V1.64N3 - Beta 12a

      OK so with this beta we're well and truly at the pointy end of the process, in this version I've gone all out last night and replaced how the VM initializes and changes scopes completely.   These changes affect function calls in general, but mainly recursive function calls, which had a few gremlins in them.   The new solution uses less memory and is slightly quicker over 10,000 function calls.    There's still remains a few dramas which can occur when recursively calling a function within a for/next loop, as well when returning values inside the recursive function call.   The latter I believe is by product of how functions are implemented, so it may not be feasible to solve without making some major changes to the runtime tech.  

      Anyway,  we need you to run as much of your programs through this build as possible.   You shouldn't really notice any difference  



Download

 [plink]Get Latest Beta (http://www.underwaredesign.com/forums/index.php?topic=1150.msg26218#msg26218)[/plink]





VM1 Classic Function Benching

      Been testing the performance of V1.64N3 function calling against V1.64L  learning edition (only version on my desk top),  the test is calling 3 pairs of  functions with an identical psub  10,000 times each.    The results show just how much overhead Functions have compared to psubs.    Today's build of V1.63N3 Beta 12B includes a few optimizations in how values are returned from User defined functions, even with those  opt's removing one move instruction per function  call, there's not a huge difference in performance.    There's some, but nothing to write home about.   



     

   
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on October 06, 2012, 09:08:30 AM
 PlayBASIC V1.64N3 - Beta 12b / 12c

     This revision focuses on fixing the known stack related recursion issues, therefore it's able to return data from inside a recursive calls.   It's also had any number of tweaks made to the stack operations to try and shave off even more execution cycles in function calls.    

      Download Bellow
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on October 08, 2012, 12:51:40 AM
 PlayBASIC V1.64N3 - Beta 12d

      Yep another step towards insanity.  Shortly after posting beta 12c, noticed a few examples that didn't work with that revision.   Managing the stack when the functions allow multiple returns and recursion is something of a nightmare.   After another rethink, ended up splitting how the data is stored, in order to avoid the possible data collisions.  Which turns out makes the call that little bit faster also.

      Today's build seems happy to run recursive functions calls with or without input parameters or return parameters.


      I'm expecting this to be the release version (if no related issues are found) so get downloading and get testing


Download



Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on October 09, 2012, 06:46:59 PM

Working ?

    So I take it beta 12D is working as normal for people (yeah.. all 3 of you, simply pathetic! ).  It's be at least good have some confirmation of it's status before releasing it.   Been doing some more doc's tidy stuff yesterday.  Added a few optional parameters here and there, like FindData default to forward mode. Stuff Like that.       

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: micky4fun on October 10, 2012, 05:36:24 AM
Hi all

sorry , yep seems fine here on my stuff ,  :)

mick :)
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: OldNESJunkie on October 10, 2012, 09:15:01 AM
Sorry Kevin,

Seems to work OK for me as well....
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: Sigtrygg on October 10, 2012, 01:48:12 PM
Hello Kevin!

Both versions of HellEagle (Map and Sprite)
work fine with Beta 12d.

Greetings

Sigtrygg
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: stevmjon on October 10, 2012, 06:23:08 PM
i program on the weekends, so i will test it then.

i would assume you would get more people downloading on weekends than during the week?

   stevmjon
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on October 10, 2012, 10:19:17 PM
Quotei would assume you would get more people downloading on weekends than during the week?

   nah, mid week is traditionally the busy time for the site.. 
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: kevin on October 11, 2012, 01:10:00 AM
 PlayBASIC V1.64N3 - Beta 12e

      It would seem the stack issues have been solved, or at least nobody posted anything that doesn't run because of it and nor can i find any local examples that fail because of it.   There's few legacy examples that don't work with newer versions of PB out of the box, often cause from tightening up or filling in some behavior, which may have been none existent  in legacy versions of PB.  

      Been disassembling a lot examples as I go, tedious yes, but the only real way to be sure about what the compiler is producing.   Noticed an oddity with Type Caching when using math short cut operators (+=, -=, ++ etc etc ) on typed variables/arrays.    Where the compiler wouldn't cache the accesses across multiple lines.  Meaning such code wouldn't be an efficient as it could be.   Had noticed this before in the Type Cache Bench Mark, but couldn't see an obvious cause.  Turned out the code generator for the math short cuts wasn't being told to cache them.  

      In previous revisions of 1.64N, this code

[pbcode]
      Me.X = Me.X +1
      Me.Y = Me.Y +1
[/pbcode]
     
       was actually quicker (at runtime) than

[pbcode]
      Me.X += 1
      Me.Y += 1
[/pbcode]
       
       Now it's the same..

       The optimizer is one of the most beneficial additions for the legacy VM's performance we're ever had.. The picture bellow shows the benchmark running on V1.64L (Learning Edition),  V1.64N3 (today's build) and PBFX V1.77.    Obviously V1.64N3 is much quicker than V1.64L with the optimizer enabled (remember both are running on VM1 runtime).  It's performing so well, it's almost as quick as the legacy VM2 runtime used in PBFX.     What's really interesting, is that edition of VM2, doesn't have Type caching or most of the compile time optimizer...   One can only imagine, how quick that'll be when implemented into Vm3 runtime.  

      This will be the release version, so get downloading and get testing !  



Download

 [plink]Get Latest Beta (http://www.underwaredesign.com/forums/index.php?topic=1150.msg26218#msg26218)[/plink]  (Updated to beta 12e 2012-oct-11th )



Function Performance

      All the stack and instruction set changes has made some fairly significant improvements to the Function Vs Psub bench mark.    We're seeing about a 15-20% speed up in function calling (from the IDE) in V1.64N3 over 1.64N2 (more if you go older).    Which equates to about 1 millisecond gain per test.   Very happy about that.   Attached is a piccy of the bench marks results.   Older results in previous pages.   

       

Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on October 11, 2012, 02:09:42 AM
I'm going to test this beta =) These numbers are very impressive!

all work very well!

p.s. I tried make video to mick4fun arcade game, first i start my fraps demo then i start playBasic and PB don't appear Editor windows.
win7x64
Maybe this is not a bug, but editor.exe really not appear.
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: stevmjon on October 11, 2012, 02:40:14 AM
to atlus

i had exacly the same issue. i think it is fraps, because my art program won't launch if i have fraps running.
a while back i even e-mailed fraps and told them about this, but they said it is not fraps, even though i have two programs that won't launch while fraps is running.
i hope this works out.

  stevmjon
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: ATLUS on October 11, 2012, 02:43:09 AM
Thank You stevmjon, now i am not alone with this issue.
Title: Re: PlayBASIC V1.64N2 (Work In Progress) Gallery
Post by: Sigtrygg on October 11, 2012, 01:06:40 PM
Tested Beta 12e and everything work fine!
Looking forward for N3 Version  :)

Greetings

Sigtrygg
Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: kevin on October 13, 2012, 02:00:08 AM

PlayBASIC V1.64N3 - Retail Upgrade

      Well, it's finally here.... have fun !



Download

  [plink]PlayBASIC V1.64N3 Retail Upgrade (http://www.underwaredesign.com/forums/index.php?topic=1182.msg26273#msg26273)[/plink]  (2012-oct-13th )


       

Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: ATLUS on October 13, 2012, 04:09:12 AM
Thank You Kevin!
Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: stevmjon on October 13, 2012, 08:05:38 PM
playbasic v1.64 N3 still thinks it's a beta?

check pic.


EDIT:  i did not install this properly. i tried to install this as a standalone program, rather than intall it as a patch.
Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: kevin on October 13, 2012, 08:13:07 PM

sigh, you'd think by now, people would have learn how to install an upgrade   
Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: BlinkOk on October 13, 2012, 08:57:22 PM
you think by now the product would auto update like every other product
Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: kevin on October 13, 2012, 10:27:58 PM
Quote from: BlinkOk on October 13, 2012, 08:57:22 PM
you think by now the product would auto update like every other product

   No trolling please..   Wish we'd thought of it (http://www.underwaredesign.com/forums/index.php?topic=1857.0)..   Far from concept,  this was tried at one point.  But it doesn't solve the problem.     To be freely available, all updates must assume must they're being installed over an existing 'complete' version, if the user manually selects a new install path during installation, then it won't work..       

 
 
Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: stevmjon on October 13, 2012, 10:35:19 PM
blimey , sorry about that.

i was too excited to install this, and completely forgot the correct method.
thanks for the update.

  stevmjon
Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: BlinkOk on October 13, 2012, 11:00:35 PM
not trolling at all. every other product does it and does it well. just solve the problems
Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: baggey on October 27, 2012, 01:32:43 AM
Keep up the good work KEVIN. A little bit of performance here and there makes a big difference!  ;D

Ive tried other languages and guess what, Im using PLAYBASIC still.

Its the best forum for backup and help!

So KEEP ON CHIPPING AND IMPROVING PERFORMANCE.

kind regards BAGGEY
Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: kevin on October 29, 2012, 11:07:54 AM
 PlayBASIC V1.64N3b - Compiler Tweaks

     While messing with the Pooyan example (http://www.underwaredesign.com/forums/index.php?topic=3710.msg26396#msg26396), noticed an issue with one the built in constants "PBCompileMode"  not responding correctly to the compile mode.   Fixing it turned out to be straight forward, but the fix made the keyword searching slower.    While looking over it,  there's obviously some baggage in those old routines, so figured I'd take the opportunity to tweak them up a bit.

    The parser performs a lot of searches trying to ID each token from the source code.   String searching is inherently messy and can be a real black hole in terms of performance, in particular when the keyword count gets high.    The structure of searches already minimize most of the work, but at some point you have to compare the likely strings together.  Even if your only comparing a hand fall each time,  that overhead soon adds up when you might be searching 1000's of times.    You can avoid much of this by adding a hash to represent the string.   The hash is just a little routine that skims the string and builds a 32bit pattern from it.    The pattern is used as further trivial reject during searches,  it's not a 100% match though, more an indicator of a close match.   So if the hashes are the same, you then compare the strings.

    So  result wise it's been pretty interesting.   I'm comparing PB1.64N2 (just because it's sitting on the desk top) with today's edition V1.64N3b.   The test code created with the following snippet.


[pbcode]
   for lp =0 to 999
         #print "Variable"+Str$(lp)+" ="+str$(lp)
         #print "Variable"+Str$(lp)+"# ="+str$(float(lp))
   next

   Sync
   WaitKey
[/pbcode]
 
   To build the test program I'm just  running this example (f7),  clicking on he Console tab and select all the text it spat out.     Then open a new project in the IDE and paste the code fragment 10 times into the main source.   So we end up with a slab of 'do nothing' code that's 20,000'ish lines long.   So there's lots of variable creation and lots of variable look ups.

   PB V1.64N2 results

Total Compile Time: 3438 Milliseconds
  Lines Per Second: 6406.34
   Number of Lines: 22025



   PB V1.64N3b results

Total Compile Time: 2286 Milliseconds
  Lines Per Second: 9634.73
   Number of Lines: 22025



     So about 30% faster compile time running on my 7 year old single core AMD system..  


Constant / Literal Strings Tweaks

     After picking over the other data types i've been looking at the string cache and not liking what i'm seeing.  There's just an excessive amount of string thrashing when searching for preexisting literals.   It does this so strings that occur more than once, aren't stored in the final program.   But the search was basically a linear search through the cache with some trivial rejects.  So it seemed like a good candidate for hashing the literal strings.   Which seems to pretty well, across a 10,000 line program with 1000 unique (but similar) string fragments.


    PB V1.64N2

Total Compile Time: 887 Milliseconds
  Lines Per Second: 11299.9
   Number of Lines: 10023



    PB V1.64N3b

Total Compile Time: 638 Milliseconds
  Lines Per Second: 15710.0
   Number of Lines: 10023


   So about 20% faster across this program.

Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: kevin on October 30, 2012, 08:35:45 AM

PlayBASIC V1.64N3b - Retail Upgrade Released

    This update includes a fix for some issues with some built in constants (like PBCompileMode) not responding to the compiler settings.    Beyond that, it also includes a number of mostly small tweaks to the variable/constants and literal searching  routines.   These tweaks improve the compile times by around 30% in programs that make heavy usage of lots of unique variables / constants or literals.     Routinely getting a compile performance of 10,000 plus lines a second on 7 year old single core AMD system.


Download

   Download  [plink]PlayBASIC V1.64N3b Upgrade (http://www.underwaredesign.com/forums/index.php?topic=1182.msg26273#msg26273)  [/plink]

Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: kevin on November 24, 2012, 09:43:16 PM
 PlayBASIC V1.64N3c - Compiler Tweaks Round #2

    Been off working on some other bits and bobs in the real world lately, but have been using PB for a lot of the grunt work, as such have noticed some oddities in some program disassembles.  The first being that the code didn't seem to screen out redundant moves between the same variable.     So if the code had the line  A = A, it'd drop a move operation for it, even though it's pointless.   Not a big deal for the odd operation, but will certainly add up if such code exists in a tight loops.

   Another oddity was occurring when reading the fields from a typed variable/array/list and storing that back in a variable.    So if you had code like X#=Player.X#,  the code generator would always drop an extra move operation.  Not a big thing in every day code, but can quickly magnify in heavy loops.  There's not a huge gain from this, it's more about stream lining the operations.    This can be seen when running the brute force bench, as there's only a about 1.5 milliseconds gain across the entire test.    It'd be very handy if you cache lots of fields or they're modestly strings.  
Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: kevin on November 27, 2012, 05:20:56 AM

PlayBASIC V1.64N3c - Compiler Tweaks Round #3

     Dropped another session into peeking through some dis-assemblies and it would seem that reading from cached type fields also had the same problem where it'd drop an extra move opcode all the time, where it's only needed some of the time.   So tweaking the code generator again and those bogus moves vanish. 

     The tests bellow compare V1.64N3 retail with today's build of V1.64N3c, both from the IDE.  The results are pretty interestingly in that even in such a small and simple test there's some gain to be had, most of that is going to be from the reduced  string thrashing, but ya get that.

[pbcode]

   Type Stuff
         x,y#,z$   
   EndType

   Dim me as stuff
   
   
   me=new stuff

   me.x=123
   me.y#=45.66
   me.z$="yeah"
   


   max=10000


   Do
      cls

      frames++
      optexpressions 1

      t=timer()   
      For tests=0 to max
         x= me.x
         y#= me.y
         z$=me.z
      next
      tt1#+=Timer()-t
      
      print tt1#/frames
      
      optexpressions 3
      
      t=timer()   
      For tests=0 to max
         x= me.x
         y#= me.y
         z$=me.z
      next
      tt2#+=Timer()-t
      print tt2#/frames
      
      Sync   
   loop   
   
[/pbcode]



Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: kevin on November 28, 2012, 09:58:12 AM
PlayBASIC V1.64N3c - Retail Upgrade Released

    This update incorporates this weeks compiler and optimizer tweaks.  Since the change only alter code generation, it can be used with V1.64N3 runtimes, which haven't been included. 


Download

   Download  [plink]PlayBASIC V1.64N3c Upgrade (http://www.underwaredesign.com/forums/index.php?topic=1182.msg26273#msg26273)  [/plink]

Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: kevin on December 08, 2012, 08:08:57 AM
  PlayBASIC V1.64N3d - Compiler Tweaks Round #4

       Been working on various tweaks to PlayMAPPER this last week, and even though i've been able to rip a few 1000 lines out of it,  the dieted version is still pretty big, weighing in just over 20K lines.   Which seems to build (on average on my system) from V1.64N3 in about 3850 milliseconds.  So almost 4 seconds to a person, which is lightning fast compared to the good old days.   The build time is about 250/350 milliseconds quicker in  the B and C revisions of V1.64N3 since they feature some of newer search optimizations, but there's a lot of function searching and Type Field searching in the program.  And while there is in most programs, it seems to really impact the performance here.

       So thought i'd take a look and see if the same thing that was applied to the constants/variables stuff would apply to everything else starting with Functions  / TypeFields, if should, but just ya never know.    Getting the function stuff working seemed to go without much of a hitch really.   The type fields weren't so pleasant.    But after a few hours of head scratching and good old fashion mind numbing fun,  it seems to be working as normal again.    The net result of what turned out into a few hours,  is the build time is now averaging 2947 Milliseconds for the same project, so a second faster, which is very noticeable improvement to the user.

      This might not sound like a big deal, but such changes not only make the compiler far more able to handle bigger  programs without that rapidly raising the build time.   They're what allow you to Edit->Test->Edit->Test in rapid succession.   For many the process is largely transparent.  Which is how it should be.




   
Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: kevin on December 09, 2012, 10:36:30 AM
 PlayBASIC V1.64N3d - Compiler Tweaks Round #5

     Made a few more tweaks the search routines tonight,  but haven't really been able to win any serious time back.  The build time felts really speedy on normal sized projects, which should help with productivity.   Another tweak I've been messing with is screening out some redundant expressions in integer operations.   I think the C revision has some of these, but the D revision includes a few more.   Basically it's trapping expressions with one of the terms is literal zero/one or two.   So an expression A=A+0  would have generate the addition operation, with possible a move operation.  But now it produces nothing.  Some other situations are thing like mults.  Where you might have a A=A*1.  Which will get stripped out.    

     In terms of the runtime performance, Addition is generally quicker than Multiplication.  So knowing this, we can recast Integer expressions that include a 2 * something in them, like the expression A=B*2, this is recast as A=B+B.   Today's build does this for you invisibly.    PB actually includes a number of these types of tweaks today.     In terms of performance,  the bench bellow runs about  1/2 a millisecond quicker (15->20%) over 100K additions.  


[pbcode]


   max=10000
   Do
      cls
      frames++

         t=timer()
            For lp =0 to max
                  A=B*2
                  A=B*2
                  A=B*2
                  A=B*2
                  A=B*2

                  A=B*2
                  A=B*2
                  A=B*2
                  A=B*2
                  A=B*2
            next
         tt1#+=(timer()-t)      
         print tt1#/frames


         t=timer()
            For lp =0 to max
                  A=B+B
                  A=B+B
                  A=B+B
                  A=B+B
                  A=B+B

                  A=B+B
                  A=B+B
                  A=B+B
                  A=B+B
                  A=B+B
            next
         tt2#+=(timer()-t)      
         print tt2#/frames
      


         t=timer()
            For lp =0 to max
                  A=2*B
                  A=2*B
                  A=2*B
                  A=2*B
                  A=2*B


                  A=2*B
                  A=2*B
                  A=2*B
                  A=2*B
                  A=2*B
            next
         tt3#+=(timer()-t)      
         print tt3#/frames


         t=timer()
            For lp =0 to max
                  A=B+B
                  A=B+B
                  A=B+B
                  A=B+B
                  A=B+B

                  A=B+B
                  A=B+B
                  A=B+B
                  A=B+B
                  A=B+B
            next
         tt4#+=(timer()-t)      
         print tt4#/frames

      Sync
   loop
[/pbcode]



     
Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: kevin on December 10, 2012, 10:55:09 PM
PlayBASIC V1.64N3d - Retail Upgrade Released

    This update incorporates this weeks compiler and optimizer tweaks (Faster keyword searching, various code generation redundancies built in).  Since these change only alter code generation, it can be used with V1.64N3 runtimes, which haven't been included. 


Download

   Download  [plink]PlayBASIC V1.64N3d Upgrade (http://www.underwaredesign.com/forums/index.php?topic=1182.msg26273#msg26273)  [/plink]

Title: Re: PlayBASIC V1.64N2 / V164N3 (Work In Progress) Gallery
Post by: kevin on January 27, 2013, 08:58:53 AM
 PlayBASIC V1.64N3d - String Comparisons

    The past week or so i've been noticing some odd behavior in one of the helper tools, which is of course written in PlayBASIC.   The behavior initially seemed to be logic error in one of the larger routines, so at first didn't worry about it, assuming it'd be a quick fix when it came time to look at it.   The mood soon changed after sifting through the code trying to locate the issue.   The particular section seemed to produce irrational results when comparing for inequality between two strings.   The more I looked the more bizarre it seemed.  

    Initially was thinking this was likely to be a by product of some recent change to code generation, where the optimizer may have been breaking this particular sequence of the instructions.  But after firing up the diss-assembler, it was fast becoming apparent the cause was else where.   Meaning the actual comparison might have been broken.  The string engine is one of the oldest parts of the runtime, we're still using the second generation of it from about 7 or 8 years ago.   But it has been tweaked over time.   It's those tweaks where little behavior changes occur.    

    After some serious scratching looking over and over the string functions, it turned out there was an issue with the string <> comparison.   At some point the routine has been updated to support batching groups of characters, but the loop expression logical was faulty can could skip most of the iterations most of the time, making for all sorts odd behavior.   But it seems fine again now.    It's worth noting that this fault occurs after V1.64L learning edition, as those builds don't seem to suffer from it.


     It might be a while before the next release, so in the mean time you can invert the state of the EQUAL. 

[pbcode]

   a$="Test"
   b$="Tes2"

; So this.. (Which is a bit iffy in V1.64M -> V1.64N  revisions)
  if    A$ <> B$
     print "<>"
  endif

; can be expressed as

  if  not (  A$=B$)
     print "<>"
  endif


; or as
  if  1-(  A$=B$)
     print "<>"
  endif


; or as
  if  A$=B$
 
  else
     print "<>"
  endif


sync
waitkey


[/pbcode]