PlayBASIC V1.64P (Work In Progress) Gallery

Started by kevin, August 31, 2013, 02:38:09 PM

Previous topic - Next topic

kevin

#45
   PlayBASIC V1.64P2 BETA #08  -  Constant Colour Alpha Blend Speed Ups #2

    Updated the strip render routines to use the newer Scaler and MMX logic for variable alpha blending.   The changes has resulted in doubling basically of the alpha performance of those effects.  Most convex render routines use the strip list back end, so circles/boxes/triangles/quads all use the same filler, but filled Shapes use the legacy draw strip interface since the order of spans isn't necessarily linear.  That interface has been tuned a few times, but when you're calling it potentially a hundred thousand times (and above) like in the following demo, then there's going to be a loss in purely function calling/passing overhead.    Which is more than you might think, even in assembly.    

  The code bellow is much like the previous example, but this time we're waving the diagonal row and swapping boxes for filled shapes..  Each shape has a variable alpha blend level.  Running in today's build of PB1.64P2 it's twice as fast V1.64P and about 60% faster than V1.64O..  

PlayBASIC Code: [Select]
   #include "blitimage"


LoadFont "Veranda",1,24,8

ClsColour=$334455

Screen=NewImage(getScreenWidth(),GetSCreenHeight(),2)
rendertoimage Screen
cls $334466

; build a table of colours
Dim Colours(1024)
for lp=0 to 1024
Colours(lp)=rndrgb()
next


Size=128

Shape =MakeBoxShape(0,0,size,size)
shiftshape shape,size/-2,size/-2

; --------------------------------------------------------------------
Do
; --------------------------------------------------------------------

rendertoimage screen
xpos=-50
ypos=-50
pixelcount=0
; set ink mode to variable alpha blend with target

inkmode 1+64
inkmode 1+16

lockbuffer

rotateshape shape,angle#,1.25

WaveAngle#=wrapangle(WaveAngle#,1)

for Alpha =0 to 750
;
inkalpha (alpha and 255)/255.0 ;512.0

ink Colours(Alpha)

; compute the size of the wave at this point along the line
dist#=cos(WaveAngle#+Alpha)*sin(Angle#)*100

; add this position to the origin position
nx=xpos+cos(360-45)*Dist#
ny=ypos+sin(360-45)*(Dist#)
drawshape Shape,nx,ny,2

; move origin position, so we're not drawing completely over each previous render
xpos++
ypos++

; increase the size of the box
;Size++
next
unlockbuffer

; tally the number of pixels
PixelCount=(Size*size)*lp


inkmode 1+16
inkalpha 0.5+cos(angle#)*0.5
angle#=wrapangle(angle#,2)

; inkalpha 0.25

; draw box using the current inkmode
; boxc 0,0,800,600,true,$605030
;
circlec mousex(),mousey(),size,true,$ff00000

ink $557788
rotateshape shape,angle#,4
drawshape Shape,400,300,2

ink -1
inkmode 1

rendertoscreen
BlitImageClear(Screen,0,0,ClsColour)

text 0,0,"Blending:"+Str$(pixelcount/1000.0)+" K pixels - MMX:"+Str$(GetGFXMMX())+" FPS:"+Str$(fps())
if spacekey()
GFXMMX 1-GetGFXMMX()
flushkeys
endif

Sync

; --------------------------------------------------------------------
loop
; --------------------------------------------------------------------




Function MakeBoxShape(x1,y1,x2,y2)

ThisShape=NewShape(4,4)

SetShapeVertex ThisShape,0,x1,y1
SetShapeVertex ThisShape,1,x2,y1
SetShapeVertex ThisShape,2,x2,y2
SetShapeVertex ThisShape,3,x1,y2

SetShapeEdge ThisShape,0,0,1
SetShapeEdge ThisShape,1,1,2
SetShapeEdge ThisShape,2,2,3
SetShapeEdge ThisShape,3,3,0

refreshshape Thisshape

EndFunction ThisSHape







ATLUS


kevin

#47
  PlayBASIC V1.64P2 BETA #08b  -  Compiler Runtime Null Pointer Errors

      After finalizing the ink colour alpha blending stuff,  added some runtime trapping to the compiler-runtime when code tries to peek/poke a null pointer.   Which just mean that if you try and de-reference a pointer that's null or query or write to a  field in UDT pointer, you're more likely to get a runtime error than a crash.    


PlayBASIC Code: [Select]
   dim pb as byte pointer
dim pw as word pointer
dim pf as float pointer
dim pi as integer pointer

print *pb
; print *pw
; print *pf
; print *pi




      Since none of the pointers are set to poke at some allocated memory, they'd be null when you tried and de-ref them.  This would normally cash,  it still will if the pointer is pointing at memory you've freed or never owned.  Can't do much about that.  

PlayBASIC Code: [Select]
   Type Stuff
a,b#,c$
Table(10)
EndTYpe

Dim me as stuff pointer

print Me.a;
print Me.b;
print Me.c
print Me.Table(a)





       Neither the release or debug runtimes will include this functionality, it's just for the compiler-runtime.





PlayBASIC V1.64P2 BETA #08 (Retail Compiler Only Beta) (8th Dec,2014)

     Beta #08 has a number of minor command set tweaks with TypeOF(), SpriteInregion() through as well as the pointer instruction sets, which now include stuff like runtime null pointer error trapping, so if you try and re-ref a pointer that's currently null that runtime will step in and give you a runtime error.   These are pointers though, and that doesn't prevent you from addressing memory you don't currently own, or that you've since released.   If your code does, it'll crash.  

      Some other changes come in the form of some rendering improvements, in particular when alpha blending a single coloured vector shape with the backdrop.   The rendering engine didn't seem to include an MMX version of that fill method, so there's was 2 multiples per pixel.    The MMX version pre-computed the blend level of the colour and can therefore double the variable alpha blend speed.      

      The demo bellow draws a snakey styled object out of alpha blended rotating  box shapes, which runs about twice as quick here now.   If you wanted to draw a convex polygon, i'd recommend using the QUAD function, which would be more efficient than a shape, since shapes are span render based, convex shapes like Quads/Boxes can be rasterized linearly.  

PlayBASIC Code: [Select]
   #include "blitimage"

LoadFont "Veranda",1,24,8

ClsColour =$334455

Screen =NewImage(getScreenWidth(),GetSCreenHeight(),2)

rendertoimage Screen

cls $334466

; build a table of colours
Dim Colours(1024)
for lp=0 to 1024
Colours(lp)=rndrgb()
next

Size=128

Shape =MakeBoxShape(0,0,size,size)
shiftshape shape,size/-2,size/-2

; --------------------------------------------------------------------
Do
; --------------------------------------------------------------------

rendertoimage screen
xpos=-50
ypos=-50
pixelcount=0
; set ink mode to variable alpha blend with target


Scaler#=1

rotateshape shape,angle#,scaler#

WaveAngle#=wrapangle(WaveAngle#,1)
startinterval(0)

lockbuffer
inkmode 1+16 ;4096

for Alpha =0 to 750
;
inkalpha (alpha and 255)/512.0

ink Colours(Alpha)

; compute the size of the wave at this point along the line
dist#=cos(WaveAngle#+Alpha)*sin(Angle#)*100

; add this position to the origin position
nx=xpos+cos(360-45)*Dist#
ny=ypos+sin(360-45)*(Dist#)
drawshape Shape,nx,ny,2


; try these
; box nx,ny,nx+size,ny+Size,1
; ellipse nx,ny,size/2,Size/2,1

; move origin position, so we're not drawing completely over each previous render
xpos+=1
ypos+=1

; increase the size of the box
;Size++
next
unlockbuffer

ThisTime=EndInterval(0)

; tally the number of pixels
PixelCount=((Size*size)*Alpha)*Scaler#

inkalpha 0.5+cos(angle#)*0.5
angle#=wrapangle(angle#,2)

inkmode 1+16

; draw box using the current inkmode
circlec mousex(),mousey(),size,true,$ff00000

ink $8faad7
rotateshape shape,angle#,6
drawshape Shape,400,300,2

ink -1
inkmode 1

rendertoscreen
BlitImageClear(Screen,0,0,ClsColour)

text 0,0,"Blending:"+Str$(pixelcount/1000.0)+" K pixels - MMX:"+Str$(GetGFXMMX())+" FPS:"+Str$(fps())
text 0,20,ThisTime
if spacekey()
GFXMMX 1-GetGFXMMX()
flushkeys
endif

Sync

; --------------------------------------------------------------------
loop
; --------------------------------------------------------------------




Function MakeBoxShape(x1,y1,x2,y2)

ThisShape=NewShape(4,4)

SetShapeVertex ThisShape,0,x1,y1
SetShapeVertex ThisShape,1,x2,y1
SetShapeVertex ThisShape,2,x2,y2
SetShapeVertex ThisShape,3,x1,y2

SetShapeEdge ThisShape,0,0,1
SetShapeEdge ThisShape,1,1,2
SetShapeEdge ThisShape,2,2,3
SetShapeEdge ThisShape,3,3,0

refreshshape Thisshape

EndFunction ThisSHape







Download


    PlayBASIC V1.64P2 BETA #08 (8th Dec,2014)




kevin


PlayBASIC V1.64P2 BETA #09 -  AFX Blitter updates

        Updated the AFX images/surfaces blitter routines, so they combined the screening logic with MMX support, which is bit of pain as VC++ tends to produce object code that won't run... Anyway, the screening means pixels at are completely translucent (Alpha channel of 0 for each pixel) are ignored and those that are completely opaque (A=255) pass through without needing to read the destination or blend the two pixels together.  This will work better for most images, as generally the alpha level of pixels in most images is 0 or 255,  of course for images where they're all translucent won't benefit from this change.

        The demo & image bellow is one of those brute force situations where it's drawing a few hundred big AFX images on screen.  With some of the test scenes it's about 20% faster, but it depends on the amount of pixels that need to be blended. 





kevin

#49
  PlayBASIC V1.64P2 BETA #09b - Rotated AFX Images + Sprites updates

      Updated the rendering engine for handling rendering AFX surfaces to 32bit surfaces, the newer code supports alpha screening and opaque pixel short cutting in MMX assembly.   The changes only bring a few more fps in the brute force tests over previous V1.64p2 revisions, but that's still a significant 5->6 millisecond saving.   Rotating images is generally about twice as slow as a straight none rotated blit.  Probably slower are certain angles also, as the data won't cache very well.    Way back in the the old 16/32bit days we'd handle such things by using pre flipped images,  you can of course do this also.  My general advise would be to minimize what you're actually drawing and pre-compute any rotations if possible.   Using a CRF in place of images tends to be even faster. So be creative with how you solve such problems.

      Interestingly when you draw images via DrawRotatedImage or rotated sprite, DrawSprite with drawmode 2 enabled the rendering backend is the same as you might expect, but there's something of a strange anomaly where rotated sprites  have a little more overhead around than they should.    Looking at the rendering code, there doesn't really seem to be any huge differences, although it does appear there's no shape clipping which does strike me as odd.   I've a feeling object level clipping is done elsewhere in the pipeline, so will have to have a closer look at that later.  There might well be some easy gains in to be had in those libraries,  but I'm not too keen to start a complete overhaul at the moment.

      With the most recent tweaks I'd say upgrade V1.64P2 is coming to an end, it was only intended to tweak those missing functions and or changed behaviors from the previous massive V1.64P update.   I say massive, as internally every command has changed, but functionality it's not significantly different to V1.64O say from the users perspective.   The true power of it lies in the combination with PlayBASIC2DLL companion tool, which can be easily seen in G2D libraries for example.  PB2DLL aren't the only benefactors with V1.64P pushing the performance barrier forward constantly.  

       Will no doubt post the final beta today sometime..
   

kevin

#50
  PlayBASIC V1.64P2 BETA #09b (Retail Compiler Only Beta) - (Avail for Registered Users ONLY)  (14th Dec,2014)


     Beta #09b includes the MMX versions of the AFX blend blending code and couple of minor command set tweaks.   I'm expecting this to be the release version, so it'd be most helpful if you'd run you code through this prior to release!



Download


  Download PlayBASIC V1.64P2 Beta09b  (14th,Dec,2014)


kevin

#51




PlayBASIC V1.64P2 _Retail Upgrade_ Now Available (29th, Dec, 2014)


   This release updates any version from  PlayBASIC  V1.63w2 to PlayBASIC V1.64P (retail) to the current retail version of PlayBASIC V1.64P.   If your current version is older than PB1.63W (pre June/July 1997), then you may need to install patch PB1.63w2 prior to this one ! (if you haven't already)


    The PlayBASIC V1.64P2  package includes updates of PlayBASIC Compiler, Release / Debug Runtimes, SLIBS,  DOCS (HELP FILES) & IDE V1.17b. 

    The V1.64P2 release is a relatively minor update to address functionality broken during the massive V1.64P update.   Beyond those bug fixes, there are of course more improvements to the compiler &  runtime command sets and debugger.

   The compiler / runtime time changes are generally improvements to the quality of the byte code the compiler produces within certain circumstances.   One that comes to mind, was the ability to completely optimizing out literal fields when querying array structures from typed pointers.    So code like the snippet bellow runs better in V1.64P2 than previous versions.   Which in turn helps PlayBASIC2DLL produce even faster machine code versions of such routines.  So that's a big win !

PlayBASIC Code: [Select]
  Type SomeStructure
IntegerArray(16)
EndTYpe

dim Me as SomeStructure pointer

Me = new SomeStructure

// such field offsets are solved at compile time
Me.Array(0) = 1
Me.Array(2) = 1
Me.Array(3) = 1
Me.Array(4) = 1

Print Me.Array(0)
Print Me.Array(1)
Print Me.Array(2)
Print Me.Array(3)




    Such compile time optimizations are useful when we want to iterate through structures of data,  so rather than bumping the ME pointer between integer fields, we could unroll the inner loop to process groups of integers and access fields at fixed offsets then  bump the ME pointer.  Which is a more efficient approach generally.   


    Changes to commands sets that users will find the most useful, can be found in variable Alpha Blending situations,  generally filling surface routines are now twice as fast when performing variable alpha blending in this version,  there's also changes to the AFX alpha blending logic which screens the alpha channel value for pixels that are fully translucent or opaque, in either case those are handled with a special case.   The performance benefit really comes down to how many pixels in the image need to be alpha blended.  But the standard tests had a 10->20% improvement without change..


    In terms of Debugging, there's two new subtle changes in the compiler runtime.  The first, is the new ability of the runtime to intervene when some pointer opcode attempts peek/poke from a null pointer.    Which should generally return a runtime error if that occurs like in the example bellow.

PlayBASIC Code: [Select]
  ; declare a ME as type Integer POinter
DIM Me as Integer Pointer

; the runtime will stop before this line is execute as ME is
; will be pointing at ZERO.. Which is memory your program doesn't
; own and would kill your program
print *ME


sync
waitkey





   The other runtime/debugger change is a mode in the debugger to Enable/Disable automatic type creation when executing a program.    The PB runtimes default behavior is to automatically allocate a type if you're writing to a structure that's currently empty.    Generally this is handy behavior as it saves you some lines of code, but can be an issue when exporting your programs to DLL since PlayBASIC2DLL doesn't support this behavior.  So if you writing library code that you're going to build a DLL of, you'll find this invaluable !

   Don't have a retail version of PlayBASIC ? and want to find out more information about PlayBASIC programming > please visit the www.PlayBasic.com and download the free learning edition.




Downloads


  Download PB1.64P2 Retail Upgrade (login required)  (29th,Dec,2014)

kevin

#52
 PlayBASIC V1.64P3 BETA #01

   Found a couple of interesting  little chestnuts in V1.64P2 over the last day.   The first was problem with the  For/Next Loop pre-screening, which appears to be broken since V1.64P beta 37.   When a loop is started, the runtime checks the range to see if there's an overflow up front, if there is the loop is skipped.  The logic was correct, but the opcode was writing to an integer variable that was being cast as integer->float->integer.  Which means some bit precision is lost.    Not to worry, this issue only appears when the loop counter is larger than 2^24, like the example bellow

PlayBASIC Code: [Select]
   For address=$70203040 to $70203040
a++
next

print a
print address

sync
waitkey


                                  
   Obviously it's pretty unlikely you've run into this issue in your everyday code, unless you've been using the packer.pba slib which is also used in other includes like the Map.pba slib..  Which is how this was discovered..  The issue has already been FIXED!


  The other fix was an issue that could occur when writing float literals to integer fields in typed pointers.  The compiler used to pass this code through to the  code generator, which would create a bogus cast operation in the byte-code before the move operation, where all it had to do, is cast the float to integer than dump that out.   Of course in this case, it wasn't returning the correct index and you could get anything written into the field..  But that's fixed now also..



kevin


  PlayBASIC V1.64P3 BETA #03 - Cleaning House

            Ok... so before we were rudely interrupted, a Beta #2 build was in the works and looking back it appears to include a built version of the packer library.    The packer library just performs some run length encoding, it's purpose was to compress small chunks of raw data in banks.  Since maps level array are basically chunks of the raw data the library was used in the maps library to keep the file sizes down.  The problem is if the data set is large, then both compress/decompress routines are is fairly slow.   Most of the time is a none an issue, but could be if you converted a picture to a map say and the level dimensions ended up almost the size of the original image.    So that's been internalized, the thing is, that was few months ago and I can't find the 'test projects that I was using to validate the compressed input/output is the same as the original library, as if it's not some legacy level would probably fail.     

            Anyway.. pressing on, today has been about cleaning the legacy VM sources up which is far from thrilling but a necessary evil as time goes on.  The main instruction set clean up will come post V1.64, which is unlikely going to be smooth sailing.   That will a lot of time, so ironing out any V1.64P issues it's important pre V1.65 as we'll be breaking a lot of new (and old) ground.



 
             

kevin

#54
 PlayBASIC V1.64P3 BETA #04 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY)  (28th Apr,2015)

     V1.64P3 is all about little fix ups so in Beta #04 you'll find mostly little hidden away errors have been address, the main one would have to be the casting errors that appears in the next FOR/NEXT opcodes with Integers.  Effectively the counting was being cast as float at some point which limits the precision to 2^24 (whole number).   It's not the sort of thing you're likely to run into in everyday looping code, unless you step through memory addresses in a for/next , which is how it was discovered.  

     So something like this,

PlayBASIC Code: [Select]
   Size=1024

ThisBank=NewBank(Size)

StartAddress=GetBankPtr(ThisBank)


For Ptr=StartAddress to StartAddress+Size-1
pokebyte ptr,rnd(255)
next


sync
waitkey





      This would break in older versions of V1.64P if the bank was allocated in memory where it's address range exceeded 24bit (2^24), but it's back the same as it used to be now.




kevin

#55
 PlayBASIC V1.64P3 BETA #05 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY)  (25th May,2015)

     V1.64P3 Beta #05 contains another minor fix up created from an earlier version of V1.64P or there abouts.   The main change here is the SpriteInRegion function, which had some dodgy comparisons in the function making it fail with some/most areas for none rotated sprites.  This function is also used when detecting if a sprite is inside a camera viewport and possible a few others.  



PlayBASIC Code: [Select]
  IMage=Newimage(64,64,2)
RendertoImage Image
cls 255

rendertoscreen
s=newsprite(100,100,Image)


; spritedrawmode s,2

setfps 30
do
cls $203040



speed#=5

if leftkey()
movesprite s,-speed#,0
endif

if rightkey()
movesprite s,speed#,0
endif

if upkey()
movespriteY s,-speed#
endif

if downkey()
movespriteY s,speed#
endif

box 100,100,600,400,false
if spriteinregion(s,100,100,600,400)
print "inside region"
endif

drawallsprites

sync
loop






kevin

#56
 PlayBASIC V1.64P3 BETA #06 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY)  (18th June,2015)

     V1.64P3 Beta #06 some parser changes to allow optional parameters in the linkDLL bindings,  unfortunately it's still only limited to Integer/Float and String fields..   I can easily expand it to support arrays/pointers in this build as the pre-processing.   The other changes can be found in the FillMemory function. Which now has a some high level bit mode to enable AND/OR/XOR modes rather than just write mode.   There's also new Packer and MAP slibs with now support the internal packing library code.   Making saving levels and loading big levels much faster..


     Here's an example of the fill memory changes.  

PlayBASIC Code: [Select]
; This example encodes a message using XOR fill mode

Message$="My Secret Message"


; The Size of our test bank in bytes
Size=Len(Message$)+1

; create bank #1
CreateBank 1,Size

; store the original message into this bank
pokebankstring 1,0,Message$,0

; show the bank
ShowBank(1)



; XOR to encode the bank data with our key of $4B
FillMemory GetBankPtr(1),Size,$4B,1+32

; show the bank to screen
ShowBank(1)

; read the bytes in the bank back as string..
EncodedMessage$=PeekbankString(1,0,size)


; USE XOR with a key of $4B again to restore the bank
; data to it's original state
FillMemory GetBankPtr(1),Size,$4B,1+32

; read the bytes in the bank back as string..
DecodedMessage$=PeekbankString(1,0,size)

; show the bank to screen
ShowBank(1)


ink -1
print "Original Message"
ink $ff00
print Message$
print ""

ink -1
print "Encoded Message"
ink $ff0000
print EncodedMessage$
print ""

ink -1
print "Decoded Message"
ink $ff00
print DecodedMessage$
print ""

ink -1
print ""





; --------------------------------------------
; refresh the screen and wait for a key press
; --------------------------------------------
Sync
waitkey





Function ShowBank(Index)
Print "Bank Contents"

Size=GetBankSize(Index)-1
; Show the bytes from this bank

For lp=0 to Size
c$=right$(Hex$(peekbankbyte(index,lp)),2)
if lp<>size
r$=r$+c$+","
else
r$=r$+c$
endif
next
print r$
print ""

EndFunction








     Read V1.64P Update Work In Progress gallery




Download


  Newer version bellow.



kevin

#57
PlayBASIC V1.64P3 BETA #08 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY)  (2nd Sep,2015)


     V1.64P3 Beta #08 includes a number of operational optimizations in regards to clipping of certain drawing functions.   Functions like LINE,BOX (and a number of others) for example would refresh the clipping viewport every time you called the function.  Which was just overkill, or at least it should be.   If you find a problem you think might be attributed to these changes then of course jump on the forums and post a bug report.    The up side is of course some more speed..  



kevin

#58
 PlayBASIC V1.64P3 BETA #09 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY)  (8th Sep,2015)

     V1.64P3 Beta #09 this one includes more migrated libraries, this time around it's the time and date libraries.   Yeah i know exciting, but it has to be done..  :(




kevin

#59
 PlayBASIC V1.64P3 BETA #13 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY)  (24th Sep,2015)

     V1.64P3 Beta #13 this moves mor legacy VM out with updates to the strings/dates and call DLL libraries.




Download


  Newer downloads on next page!