UnderwareDESIGN

PlayBASIC => Show Case => Topic started by: kevin on May 25, 2010, 01:37:57 AM

Title: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on May 25, 2010, 01:37:57 AM

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


PlayBASIC V1.64M  (Work In Progress) Gallery (May 25, 2010)


     This thread will document the changes being made for the PlayBASIC 1.64 revision M .


    For OLDER upgrade work in processes see,

    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)


    For NEWER upgrade work in processes 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)

    See  PlayBASIC V1.64N2 / V1.64N3  (http://www.underwaredesign.com/forums/index.php?topic=3833.0)

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






PlayBasic V1.64M  Beta 1


     Like virtually all upgrades, work started upon the V1.63M revision almost immediately after building the previous package.   The focus and objectives of this upgrade are primarily to improve core functionality of the command sets.  Which is largely inherited from the  previous outline(s) of V1.63L.  Which is likely  to consist of various small, but helpful changes to  font,mapping,sprites, cameras and worlds command sets.  

      One area I'm particularly looking forward to, is taking better advantage of the some of the more recent parser additions, such as optional parameters.   While i've got a small list of commands that i want to add some extra controls to, it'd be nice to get some user thoughts as well.  So it'd be helpful if you'd make your way to the requests thread bellow.  

      To add your ideas see ->  User base survey of optional parameter additions for PlayBASIC V1.64M (http://www.underwaredesign.com/forums/index.php?topic=3441.0)  (Don't post them here!)


       So far, V1.64M only contains a few small changes.  So far the one that demonstrates the focus best,  would be today's additions to the MakeBitmapFont  command.    As you know, this function converts the windows GDI (True Type / Windows Bitmap) font to a bitmap representation.   What i always wanted to do, was include optional flags to instruct the builder what type of font.    Video Bitmaps, FxBitmap or the newly CRF.  To be honest CRF basically makes All Bitmap modes obsolete, but we really have to retain them for legacy, at least at this point.   Anyway, what's been added, is the ability to make a CRF version from a windows true type internally.   You'll also be able to make FX bitmap version if you want also.  But the command will default to a video bitmaps, to retain backward compatibility.  

       Example,
[pbcode]

   screen=newfximage(800,600)

   loadfont "Arial",2,80,0
   t=timer()
   MakeBitmapFont 2,$ffffffff,8   ; Convert GDI font to CRF (BITMAP)
   t=timer()-t   
   fontdrawmode 2,1      ; set it alpha blend mode

   Do

      rendertoimage screen
      c1=255
      c2=rgb(100,40,100)
      shadebox 0,0,800,600,c1,c1,c2,c2
      
      setcursor 0,0         
         alpha=128+cosradius(angle#,127)
         angle#=wrapangle(angle#,2)
         ink argb(alpha,255,0,0)
         lockbuffer
            setfont 2
            Print PlayBasic$
            
            print "BuildTime:"+STR$(t)+" Ticks"
            print "FontType:"+STR$(getFontType(2))
            print "FPS:"+STR$(fps())
         unlockbuffer

         rendertoscreen
         drawimage screen,0,0,false

      Sync
   loop   
[/pbcode]

      Currently this only works when converting  Windows fonts to CRF,  you can't convert Bitmap,FXBitmap fonts as yet.  But that's the objective.  This will allow you to load a bitmap font, grab the chr's, then convert it CRF.   CRF's basically render quicker (and to any surface), support Dynamic INK changes and even respond the ink's ALPHA channel (depending upon the render mode).    

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on May 26, 2010, 12:53:41 PM
 PlayBasic V1.64M  Beta 2 - Convert Bitmap Fonts to CRF format

   Been tapping away on the font library today,  so far i've been able to tweak up a lot of old code.   The True Type to  Bitmap/ FX & CRF routines are a lot sharper now.   The FX conversion is much faster.   It'll convert a 80 point font (Arial) to FX in about 150 milliseconds.  The older routine struggled to do that in 5500 milliseconds (Yes.. That's 5 and 1/2 seconds !)...

[pbcode]


   screen=newfximage(800,600)
   ;screen=0

   ; convert the default font to CRF   
   MakeBitmapFont 1,$ffffffff,8   


   ; Load another (bigger) font that's we'll convert
   loadfont "Arial",2,80,0
   t=timer()
         ; Conversion methods
         ; 2= Video Bitmap
         ; 4 = FX Bitmap
         ; 8 = Compressed Raster Font
   preparefxfont 2
   MakeBitmapFont 2,$ffffffff,8   

   t=timer()-t   
   fontdrawmode 2,1      ; set it alpha blend mode

;   NullPixel   =point(0,0)

   Do

      rendertoimage screen
      c1=55
      c2=rgb(100,80,50)
      shadebox 0,0,800,600,c1,c1,c2,c2
      
      setcursor 0,0         
         alpha=128+cosradius(angle#,127)
         angle#=wrapangle(angle#,2)
         ink argb(alpha,255,0,0)

            setfont 2
            lockbuffer
            Print PlayBasic$
            
            unlockbuffer
            setfont 1
            print "BuildTime:"+STR$(t)+" Ticks"
            print "FontType:"+STR$(getFontType(2))
                  print "FPS:"+STR$(fps())

         rendertoscreen
         if screen then drawimage screen,0,0,false

      Sync
   loop   

[/pbcode]


     You can also convert FX fonts to CRF now.    In the demo above, it's timing how long it takes to convert from True Type to FX , then convert from FX to CRF.    When we're converting from bitmap sources to CRF, the font in the CRF representation are 32bit.    Which means that you can now load in any old school bitmap font, and convert it to CRF.  

    Bellow is an updated version of the (5 year old) Bitmap Fonts example from the PB example pack.  In this version we're loading the bitmap font (and converting it) using an updated edition of the helper library.  The new version allows us to optionally select the font type, so the bitmap data can be loaded and imported and made ready for use in whatever bitmap format we need.


[pbcode]

   Screen=NewFXImage(800,600)
; Include the FONT Extras library
   #Include "fonts"

 ; Convert the default Font (courier) to a COmpressed raster Font
;   FontMaskColour 1,$ffffff
  MakeBitmapFont 1,$ffff00,8

 
 ; Build Chr/Image map conversion string for this font
  ChrMap$=         " !"+Chr$(34)
  ChrMap$=ChrMap$+ "    '()   -./0123456789:  = ? abcdefghijklmnopqrstuvwxyz"
  LoadBitmapFont(path$+"gfx\Bitmap_Font.bmp",5,ChrMap$,30,16,17,4)
   FontDRawMode 1,1

 ; Build Chr/Image map conversion string for this font
  ChrMap$=" !"+Chr$(34)+"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz"
  LoadBitmapFont(path$+"gfx\Fresh.png",10,ChrMap$,30,32,25,8)


 ; Build Chr/Image map conversion string
  ChrMap$="abcdefghijklmnopqrstuvwxyz0123456789.,-:!?+() "
;   LoadBitmapFont(path$+"gfx\FontEf.png",11,ChrMap$,30,32,32,8)


   cx=GetScreenWidth()/2
   repeat
      Cls 0
      rendertoimage Screen
      setcursor 0,0
;      Cls $103f0f
      c1=55
      c2=rgb(100,80,50)
      shadebox 0,0,800,600,c1,c1,c2,c2

      
      SetFont 1   
      CenterText cx,70,"...this is just the good old courier font..."
      Print Hex$(GetFontMaskColour(1))

      if GetFontStatus(5)
         SetFont 5
   ink $80ff00ff
         CenterText cx,150,"...this is an ok custom bitmap font..."
         CenterText cx,200,"..custom bitmap font..."
      endif
      
      if GetFontStatus(10)
         SetFont 10
         CenterText cx,300,"...but this one is..."
         CenterText cx,350,"...much nicer!!!..."
      endif   

      if GetFontStatus(11)
         SetFont 11
         CenterText cx,450,"..press esc to quit.."
      endif
      rendertoscreen
      if Screen
         drawrotatedimage  Screen,400,300,Angle#,1.5,1.5,-400,-300,false   +8         
         angle#=wrapangle(Angle#,0.25)
      endif
      Sync
   until spacekey()<>=0
   

[/pbcode]



Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on May 27, 2010, 02:37:13 PM
  PlayBasic V1.64M  Beta 2b - Creating CRF Fonts Internally

    Before today, the only fonts you could create internally were VIDEO BITMAP (CreateBitmapFont) and FX BITMAP (CreateFxFONT) fonts.    You're now able to create COMPRESSED RASTER FONT using CreateBitmapFont, as well as FX's also.

     CreateBitmapFont now has an optional format parameter  (CreateBitmapFont FontIndex,MaxChrWIdth,MaxChrHeight,Format=2).    The format parameter defaults to the Video Bitmap (format=2)  for backward compatibility with older code ,  but if you include the Format parameter you can select if the font is in either FX (Format=4) or CRF (Format=8) formatted internally.  

     So,

      CreateBitmapFont FontIndex,FontIndex,MaxChrWIdth,MaxChrHeight,4

      is the same as

      CreateFxFont FontIndex,FontIndex,MaxChrWIdth,MaxChrHeight
 
      It's question of what you find more readable.  

 
      Bitmap and FX fonts are not compressed formats.  CRF stores the character pixel data is a pre-compressed and ready to draw form.  To import characters, we use the GetFontCHR function as normal.   This function will copy a block from pixel data from the current surface, then convert / compress it.   While it's a fairly complex process internally, it's very reasonable in terms of speed.   The following demo only takes about 130-150 milliseconds to convert the font.

      In this test, the following code loads a  type font in and CRF, then the routine basically copies the font manually.  The only difference is that the copied version has lines drawn across the letters to give it a retro effect.


[pbcode]


   ; Load the
   LoadFont "Arial",1,80,0
   MakeBitmapFont 1,$ffffffff,8      ; Convert this to CRF, so we can draw to
                                    ; fx surfaces

   ; Get the widest and highest chr's of this font
   Width      =GetFontWidth(1)
   Height   =GetFontHeight(1)

   ; Create an AFX formated image  (always 32bit)
   image      =NewIMage(Width,Height,8)
   
   starttime=timer()   

   ; Create a empty CRF font, with a max chr width & height
   CreateBitmapFont 2,width,Height,8

   ; run through and grab the characters of our font
   For lp=1 to 256
      ; direct rendering to the AFX formated image
      rendertoimage image

      ; clear it to rgb(0,0,0)  BLACK
      Cls 0

      ; get the width of this chracter from font #1  
      Chrwidth=getFontChrWidth(1,lp)

      ; Set the width of this chr in the font we're creating
      fontchrwidth 2,lp,ChrWidth

      ; draw this character to the AFX image
      text 0,0,chr$(lp)

      ; black out every second line in this character.
      For ylp=0 to Height step 2   
         linec 0,ylp,width,ylp,rgb(0,0,0)
      next

      ; grab the image data starting at position 0,0 on the curent surface
      ; and convert it to a Bitmap font character.   In this case
      ; since the font is a CRF, it'll automatically compress the pixel
      ; data for us.  
      getFontchr 2,lp,0,0
   next

   TotalTime=Timer()-StartTime
   ; redirect rendering back the screen
   rendertoscreen

   setfont 2
   ink $ff00ff00
   print "Here's our custom font"
   print "looks a bit like those old"
   print "green screen monitors"
   print ""
   print "Conversion Time:"+STR$(TotalTime)

   Sync
   Waitkey   


   
Do
   cls 0
   g=128+cosradius(angle#,127)
   angle#=wrapangle(Angle#,1)   
   ink argb(255,0,g,0)
   print "Here's our custom font"
   print "looks a bit like those old"
   print "green screen monitors"
   print ""
   
   Sync
loop

[/pbcode]

   If you have a look at the attached picture, you'll no doubt notice the 'scan lines'  better.    Those eagle eyed PlayBASIC users might be thinking, there's nothing really new in this demo.   Well, yes and no, you can certainly create the same effect with the using Bitmap & FX bitmap fonts.   But, CRF formatted fonts can respond to the INK colour.   In the second part of the demo we're showing this.    Another plus, is that the pre-compression removes much of the redundant pixel rendering, making it generally speaking a more optimal drawing solution for text.




 PlayBasic V1.64M  Beta 2b - PlayBASIC Logo - Using CRF Fonts For Animations

    Being able to create crf's internally opens up a number of interesting possibilities. One idea, might be using CRF's for pre-calculated animations.   In other words drawing some animation sequence, then storing the frames, not as images, but as font characters in a CRF.   Since the CRF is compressed it's a fairly compact storage format, but if the frames sequence varies a lot in size, then we'll get a more optimal rendering, due to less pixels actuall being drawn.

    In this example, i'm creating a 32 frame animation of the PB logo spinning.  The frames are pre-filtered and have alpha channel.    Then i'm drawing this animation on screen 100's of times dynamically tinted with the link colour.  Even though the demo is overkill really, it runs quite nicely...

[pbcode]

   Logo=LoadNewAFXImage(Path$+"PlayBasicSig.png")

   Width=400
   Height=400

   CreateBitmapfont 2,Width,Height,8

   IMage=NewImage(width,height,8)
   
   Frames#=32
   For lp=64 to (64+Frames#)-1
      rendertoimage image
      Cls 0
      Angle#=(360/FRames#)*lp
      rendertoimage image
      hx=GetImageWidth(logo)/-2
      hy=GetImageHeight(logo)/-2
      drawrotatedimage logo,Width/2,Height/2,Angle#,1,1,hx,hy,false+8         
      getfontchr 2,lp,0,0
      rendertoscreen
      cls 0
      print str$(lp)+" of "+str$(Frames#)      
      sync
   next

   fontdrawmode 2,1


   screen=newimage(800,600,2)
;   setfps 60
   logocount=1
   do
      rendertoimage screen
      c1=rgb(55,20,220)
      c2=rgb(100,20,20)

      shadebox 0,0,800,600,c1,c1,c2,c2
      
      setfont 2
      ink $80ffffff
      For lp=-200 to LogoCount
         xoffset=lp*10
         Yoffset=lp*5
         ThisFRame=mod(FrameCount+lp,Frames#)
         text Xoffset,Yoffset,chr$(64+ThisFrame)   
      next

      FrameCount+=1
      if frameCount=>Frames# then FrameCount=0            

      if Upkey()
         logocount+=1
      endif

      if downkey() and LogoCount>1
         logocount-=1
      endif

      rendertoscreen
      drawimage screen,0,0,false          
      setfont 1
      print LogoCount

      Sync
   loop


[/pbcode]


Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on May 30, 2010, 01:58:48 PM
  PlayBasic V1.64M  Beta 4 - Final Touches On Fonts

     I've been tinkering away with beta 3 -> 4 beta over the weekend.  A number of small tweaks have been added.  Mostly in the form of  more  optional parameters for built in functions.  But i've added the odd function also, such as GetSurfaceType().  Which acts like it's brothers,  but this one returns the type (Video, FX,AFX) of the current surface.      Previously you'd have to use   ThisSurface=GetSurface() ; Then Query the type using getImagetype().  

    Anyway, my current focus is wrapping up the changes to the font engine.   All of the code is basically written, it just needs some testing  to ensure there's ample conversion and support for mismatched rendering types.    The latter,   can cause a few WTF moments for those you feel reading the manual isn't for them.   The classic example of this, is when a person creates an FX surface and tries to draw some GDI text onto it..  Hey presto, nothing gets drawn.   In retrospect, it probably should have popped a big red flashing runtime error :), but too late for that now.   You see, if you try and do this in  V1.64M, the text will be drawn onto the FX...    Well, that's what it appears like.  Internally the font is being converted to a CRF prior to drawing.   The font is still officially a GDI font in eyes of PlayBASIC,  so the rendering engine only uses the crf representation when drawing to a FX surfaces.

    Here's a bit of an example...  Thrilling stuff I know !  :)

[pbcode]


   loadFont "arial",1,48,0

   Cls 255

   Screen=Newimage(800,600,2)
   
   rendertoimage Screen
   
   print "hello world"

   ink $ffff0000   
   print "This is text drawn using a local CRF"
   
   rendertoscreen
   
   drawimage Screen,100,10,false

   ink $ff00ff00
   print "Normal GDI render to the screen"
   Sync
   waitkey

[/pbcode]



 Rendering Video Bitmap Font to FX surface

    Font rendering now supports rendering Video Bitmap fonts to FX/AFX surfaces.  It's really only implemented for completeness of the font library.   While it's possible,  you'd get better performance using a CRF or FX formated font.  But it's there if you really... really.... need it.      

    In this little example we're loading a windows font, converting it into a video bitmap representation stored on the GPU,  then we're creating an FX surface (System memory surface) and drawing the character set (video bitmaps) onto it.  

[pbcode]
   LoadFont "Arial",1,32,0
   
   print "Windows Font"
   print "Type:"+STR$(getFontTYpe(1))
   
   MakeBitmapFont 1,$ff00ff
   print "Video Bitmap Font"
   print "Type:"+STR$(getFontTYpe(1))
   
   Width   =getFontWidth(1)
   Height=getFontHeight(1)

   Screen=NewFXimage(Width*16,Height*16)
   rendertoimage Screen

   for ylp=0 to 15
      For xlp=0 to 15
         Xpos=xlp*width
         Ypos=ylp*height
         drawfontchr 1,ThisChr,xpos,ypos,true
         inc ThisChr
      next
   next

   rendertoimage 0
   
   drawimage Screen,300,0,false
   
   Sync
   waitkey

[/pbcode]

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on June 01, 2010, 11:50:34 AM
  PlayBasic V1.64M  Beta 4/5- Better Support For Mismatched Surface Types

    Still slaving away on those final touches to the font engine.   Ran into something of a strange anomaly  yesterday where one of the font conversion routines would constantly come out blank.. Had me scratching my head for a few hours that one.  Finally tracked the issue down, which turned out to be caused by the image blitting library, which was missing some drawing combination's.   Namely when dealing with AFX surfaces.   While you can draw AFX surface onto virtually everything else,  some formats couldn't be drawn onto them.   Fixing that made the font conversions work as expected.   Although I think there's probably a few comb's still missing in some other core commands, such as getImage or CopyRect.    But i haven't tested that as yet.

    The font command sets are looking pretty good in terms of flexibility with the removal of some nasty gotcha moments.  Now you can pretty much convert all the font types, and render all the various types to any surface you wish.   Which is something that wasn't possible before.    Another addition, is the ability to save a font.    So far, you can only save in CRF format.  I could add a saver for raw FX or Bitmap font data, but that seems like a waste since we have crf :).    Saving a font will mean that you'll be able write some code to create your own crf's  or import your font from another tool and then save it out as CRF.  Remember, while a CRF might be called a Compressed Raster FONT,  they can hold any graphics data.. So be creative !


 SaveFont Example

   So here's a bit of example of how you can import an classic bitmap font into PB, then save it out in CRF format.  


[pbcode]

   path$=" THE LOCATION OF THE FRECH.PNG file on your computer"

 ; Include the FONT Extras library
   #Include "fonts"

 ; Build Chr/Image map conversion string for this font
  ChrMap$=" !"+Chr$(34)+"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz"

 ; Load this bitmap font in as FX bitmap font
  LoadBitmapFont(path$+"gfx\Fresh.png",10,ChrMap$,30,32,25,4)

   ; Save This FX Bitmap Font to disc. All saved fonts are exported in
   ; CRF format
   SaveFont "C:\FreshFont.crf",10

   ; load the newly saved CRF into font 1
   LoadFont "C:\FreshFont.crf",1

   ; draw a message on the screen in the current ink colour
   centertext 400,100,"hello world"

   ; draw this bitmap font with a custom ink colour
   ink $ff0000
   centertext 400,150,"hello world"

   ; show the message to the user   
   Sync
   waitkey
   
[/pbcode]


  Attached is the source font (it's sitting in your PB projects folder under GFX)  as well as what the demo outputs.   As you can see, making your own font conversion routines shouldn't be too difficult.

 
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on June 02, 2010, 08:15:54 AM
  PlayBasic V1.64M  Beta 5- Dynamic Font Quantity Controls

     While picking over he ashes of the font lib, I noticed a couple of omissions and different functionality from other command sets.   One of the most notable is the omission of users management of the size of the fonts table.   So to address this we've added FontQuantity, which acts like it's brothers ImageQuantity, SpriteQuanity ..etc   it lets the user define the size of the PB font table.  The table defaults to 64.  So older versions of PB could only hold 64 fonts loaded at one time.   While it's unlikely you'd need more really,  this was a fixed limitation.  Moreover, functions that request a FREE (GetFreeFont()) or NEW (LoadNewFont) font,  will automatically resize the font tables for us.  So if we are using a lot of a fonts we don't have to manually take care of the FontIndexes..  


[pbcode]

   t=timer()
   FontQuantity 7

      For lp=2 to GetFontQuantity()
         LoadFont "Arial",lp,32+(lp*4),0
         Select Rnd(4)
               case 1
                  Makebitmapfont lp,$00ff00,2
               
               case 2
                  Makebitmapfont lp,$ff0000,4
               
               case 3
                  Makebitmapfont lp,rndrgb(),8
         endselect
         setfont lp
         print "Testing"
      next
   t=timer()-t
   print "done"
   print t
   sync
   waitkey
   waitnokey

      
   fontquantity 2
   Cls
      For lp=1 to GetFontQuantity()
         setfont lp
         print "lp:"+str$(lp)+"  "+(GetFontName$(lp))
         print str$(getfontstatus(lp))+" Type: "+str$(GetFontType(lp))
         
      next
   setfont 1

   print "done"
      
   Sync
   waitkey
[/pbcode]
   

      Moving on from that, i've made a few changes to the VM instruction set to help detect when rendering from a font that doesn't exist.  While it'd pick up the error previously, it wasn't trapped during Print/TEXT operations. So the runtime would report the error on the wrong line.  Causing some confusion as to what is wrong..

      eg..

[pbcode]

   ; remove the default font
     DeleteFont 1

   ; If we try and print now, it'll halt execution on the print line, since there' no output font selected.
     print "Hello"

   ;  Refresh screen
     Sync
     WaitKey

[/pbcode]


   In this example, older versions of the runtime wouldn't halt on the PRINT statement, rather the error would cascade down and be reported as being cause by the  SYNC, WAITKEY, or some other operation in your program.   Not doubt giving you one of those WTF moments...




 Font Command/Function Optional Parameters in V1.64m (Work In Progress)

   Here's a  bit of a list of the update font command parameters  (cut from the Histroy),  Most of the optional stuff is just to shortcut a procedure.

[pbcode]

   * Font Command Set Changes

      - LoadFont Filename$,FontIndex, [Size=0], [Style=0], [BitmapFormat=1]

                  ; The bitmap format parameter lets you load and convert the
                  ; loaded font in one command.  
   
      - Fontindex=LoadnewFont(Filename$, [Size=0], [Style=0], [BitmapFont=1] )



      - FontIndex=NewBitmapFont(width,height,[BitmapFormat=2])
              This command has a new optional param so you select what type of bitmap font it creates.

 

      - SaveFont Filename$, [FontIndex]  

             FontIndex is optional and defaults to the the current font if left out.


      - FontQuantity NumberOfFonts    - Expands or shrink the fonts table



      - DrawFontChr FontIndex, ChrIndex, Xpos, Ypos, [Transparent=1]
             Transparent is optional and defaults to TRUE, so chr will be drawn

      - GetFreeFont()

            now includes auto font quantity management. So it'll always Return a valid font index.

      - LoadNewFont()  also includes autofont quantity management.



      - MakeBitmapFont ThisIndex, Colour, [Format=2]

            This command lets you choose the type of the bitmap font.


      - MakeBitmapFont support various conversion methods such as,
         
                                       * Windows GDI fonts To Video Bitmap      (MakeBitmapFont ThisFont,Colour,2)
                                       * Windows GDI fonts To FX  Bitmap        (MakeBitmapFont ThisFont,Colour,4)
                                       * Windows GDI fonts To Compressed Raster (MakeBitmapFont ThisFont,Colour,8)
                                       * Bitmap fonts To FX BITMAP               (MakeBitmapFont ThisFont,Colour,4)
                                   * Bitmap Fonts To Compressed Raster       (MakeBitmapFont ThisFont,Colour,8)
                                       * FX Bitmap fonts To BITMAP             (MakeBitmapFont ThisFont,Colour,2)
                                       * FX Bitmap Fonts To Compressed Raster  (MakeBitmapFont ThisFont,Colour,8)

 







      - CreateBitmapFont ThisFont,ChrWidth,ChrHeight,[Format=2]  

               - The FORMAT is optional and defaults to bitmap (Format=2) for backward compat reasons.

                 It also supports  FX font (format=4) and CRF (Format=8) types.


      -  GetFontChr has improved Bitmap font support.

                                      - It's now able to get pixel data from various surface formats and convert them to the
                                          fonts internal format, be it Video Bitmap (2), FX bitmaps(4) Or even 32bit CRF (8).  

[/pbcode]



   Here's an example of using updated the LoadNewFont() function.  This bit of code load the Verdana font, and auto converts it crf for you.  

[pbcode]

   Font=LoadNewFont("Verdana",48,1,8) ; load it as bold and convert it to crf
   SetFont Font
   print "Hello World"
   
   Sync
   waitkey


[/pbcode]


Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on June 03, 2010, 01:00:44 PM
  PlayBasic V1.64M  Beta 6 - Compile Time Improvements

   The updated font library is done now, but before tackling the next big thing, i've been picking through the command set looking for an those obvious small omissions & tweaks.  This in turn, has set off a chain of events that has found me spending most of the day updating the compilers re-solver abilities.   Over time, this part of the  compiler has become far less functional then it originally was.   Some of this seems to be caused from the push towards changing the underlying runtimes, and how it now handles math +string functions.    After really looking at the pre-solver, the only logical option was to dive in kick it into shape.  Which has meant a lot of testing basically.  

    One  good thing that's come of the the re-write (apart from the better pre-solve support) , has been taking a much closer look see at some of the compilers string & token functions.   Many of which haven't been touched for years, so with a little bit tinkering i've been able to dramatically improve the speed of that library.   Many of the core functions in the compilers string library are now over 20 times faster.    Granted this is not something you're really likely to really notice at compile time, but as your code gets larger, the more important these types of changes are to compilation speed.  


    The following test snippet, is demo'ing the resolve ability.  In case you're not sure what this actually is ? - Well, it just means that when the compiler see's certain built in functions being passed constants, it can solve these functions during compile time, rather than exporting the code.   So the runtime doesn't have to perform the calculation, as the compile just stores the answer.  

   A good example of a solvable function would be something like,


  Print  Cos(45)


   The Cos(45) function in this code can solved during compilation so the only code this expression generates is Print 0.707107

   
  Some ugly test code ,    
   
 
[pbcode]

   // Compile Time Replace functions
   constant Replace_TEST1$   =replace$("Hello Bill","Bill","World",1,false,false)
   constant Replace_TEST2$   =replace$("Hello Bill",autocaps$("BILL"),"World",1,true,false)
   constant Replace_TEST3$   =replace$("Bill BILL bill bIll",autocaps$("BILL"),"Dude",1,true,false)

   print Replace_TEST1$
   print Replace_TEST2$
   print Replace_TEST3$

   Show()


   // Compile Time InString functions
   constant Instring_TEST1   =Instring("Hello World","World",1,true)
   constant Instring_TEST2   =Instring("Hello World","world",1,true)
   constant Instring_TEST3   =Instring("Hello World",autocaps$("world"),1,false)

   print Instring_TEST1
   print Instring_TEST2
   print Instring_TEST3

   Show()


   // Compile Time String functions
   constant AutoCaps_TEST$   =autocaps$("this is a bit of text")
   constant Lower_TEST$      =lower$("LOWER CASE TEXT")
   constant Upper_TEST$      =Upper$("upper case text")
   constant Flip_TEST$      =Flip$("Flipped Text")
   constant Make_TEST$      =Make$("Hello",5)
   constant Insert_TEST$   =Insert$("Hello World","Nice ",6)
   constant Digits_TEST$   =Digits$(123*1000+456,8)
   constant ASC_TEST         =asc("a")

   
   print AutoCaps_TEST$
   print Lower_TEST$
   print Upper_TEST$
   print Flip_TEST$
   print Make_TEST$
   print Insert_TEST$
   print Digits_TEST$
   print ASC_TEST

   Show()


   // Compile Time BIN & HEX
   constant BIN_TEST$=bin$(255)
   constant HEX_TEST$=hex$(255)

   print BIN_TEST$
   print Hex_TEST$

   Show()

   // Compile Time VAL() pre-solves
   ; solve as integer
   constant iVal_Test1=Val(" 123.456    ")
   constant iVal_Test2=Val(" 123.456    ")

   ; as float
   constant fVal_Test1#=Val#(" 123.456 ")
   constant fVal_Test2#=Val#(" 123.456 ")


   print iVal_Test1
   print iVal_Test2

   print fVal_Test1#
   print fVal_Test2#

   Show()



   // Compile Time CutLeft$() + CutRight$() pre-solve   
   constant CutL_Test1$   = CutLeft$("Hello World",5)
   constant CutR_Test1$   = CutRight$("Hello World",5)

   print CutL_Test1$
   print CutR_Test1$

   ; solved at runtime
   t$="Hello World"
   print CutLeft$(t$,5)
   print CutRight$(t$,5)
   
   Show()
   


   // Compile Time Pad$() pre-solve
   constant PadTest1$   = Pad$("Hello World","-",0)

   print PadTest1$

   Show()


   // Compile Time STR$() pre-solves
   constant StrTest1$   = str$(-123)
   constant StrTest2$   = str$(123.001)

   print StrTest1$
   print StrTest2$

   Show()
   


   // Compile Time ASC() pre-solve

   print StrTest1$
   print StrTest2$

   Show()

Function Show()

   Sync
   WaitKEY
   waitnokey
   cls
endfunction

[/pbcode]



 PlayBasic V1.64M  Beta 6b - optional Params support in pre-solver


  This working away at the pre-solver,  which is pretty boring stuff but it can't all be fun and puppy dogs.   The following example is using the compile time features to format a date.    Not that most useful or complete examples but it'll do as an example.  


[pbcode]

   constant Date$=autocaps$("01 AUG 2010")
   
   #if (Instring(Date$,"01 ")=1)
      constant TodaysDate_1$ = replace$(date$,"01 ","1st ")
   #else

      #if (Instring(Date$,"02 ")=1)
         constant TodaysDate_1$ = replace$(date$,"02 ","2nd ")
      #else

         #if (Instring(Date$,"03 ")=1)
            constant TodaysDate_1$ = replace$(date$,"03 ","3rd ")
         #else

            #if (Instring(Date$,"21 ")=1)
               constant TodaysDate_1$ = replace$(date$,"21 ","21st ")
            #else
               constant TodaysDate_1$ = replace$(date$," ","th ",1,true,true)
            #endif
         #endif
      #endif
   #endif
   constant TodaysDate$ = replace$(TodaysDate_1$," ",",")

   print TodaysDate$
   sync
   waitkey
   

[/pbcode]


  This outputs "1st,Aug,2010".   The interesting thing about this chunk of code is that it's almost entirely resolved  at compile time. So the actual output code the runtime is executing is basically this (depending  upon the input date) would be something like this...

 Print "1st,Aug,2010"
 sync
 waitkey


  If you're wondering why this type of stuff is useful to the end programmer, well it allows us to switch sections of the code IN/OUT at compile time.   So we can use flags in our code to tell the compiler how built certain bits our program, or even exclude or modifity it.

  One common usage would be when you're building game is that you can add some compile time logic to change the loading process, or include /exclude title screens , debug code , based upon the type of the compile you requested.  


  PB has a built in constant called PBCompileMode.  This constant is set to different values depending upon what build mode you selected.  If you're testing your code from the IDE (pressed F5), then you can embedd  logic in your code that's only visible when you're testing it.  If you build an stand alone exe (f4), the compiler could set to ignore a section of code.  

 
[pbcode]

   #if PBCompileMode=0
      print "Running from the editor"
      print "put my debug code into the game"
   
   #else
      print "Code in the final game"
   #endif

[/pbcode]


       Since the #IF #ELSE #ENDIF  logic is executed during compilation, the compiler outputs two different bits of code depending upon the compile mode constant.

    If you select F5 (Running your game from the IDE) it'd output..

      print "Running from the editor"
      print "put my debug code into the game"


   if you selected to build an exe (f4)  it'd output

      print "Code in the final game"


   So when we build our EXE, the compile completely ignores the DEBUG code..  The beauty here is that is done for us at compile time.   We don't have to switch it on to build our final game...




   So

     
 
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on June 05, 2010, 02:20:47 PM
  PlayBasic V1.64M  Beta 7 - Download Available

    Here's the current state of the update for beta testing by the user base.    Remember to read the history  for a complete list of the additions / changes..


 Download

   Deleted - Newer Beta's bellow.



Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on June 08, 2010, 12:35:15 PM
  PlayBasic V1.64M  Beta 8 - Suspended

     Unfortunately i've  run into some serious head aches building the compiler in recent days.   Meaning, this upgrade will have to be put on hold until a solution can be found.  

    [plink] READ ARTICLE (http://www.underwaredesign.com/forums/index.php?topic=338.msg22671#msg22671) [/plink]
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on June 11, 2010, 05:45:36 PM
  PlayBasic V1.64M  Beta 8 - Continues

     The aforementioned issues appear to have been solved now,  so we should be able to press ahead with this upgrade.

  [plink] READ ARTICLE (http://www.underwaredesign.com/forums/index.php?topic=338.msg22678#msg22678) [/plink]
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on June 13, 2010, 12:33:18 AM
  PlayBasic V1.64M  Beta 9 - Download Available

    This is critically important beta, we urge ALL RETAIL users to test it !  


 Download

    Deleted -> Newer Version bellow


Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on June 15, 2010, 02:42:04 AM
 PlayBasic V1.64M  Beta 10 - Download Available

    This is critically important beta, we urge ALL RETAIL users to test it !  


 Download

   Deleted, Newer version bellow.

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on June 21, 2010, 09:22:17 AM
  PlayBasic V1.64M  Beta 11 - Compile Time Pre-Solver Improvements (Cont)

  With the ordered chaos of the last week or so behind me now, it's very refreshing to get back something as boring as picking through the pre-solver library.. But that's what i'm doing....   yay..


[pbcode]

   constant RGBAND_TEST1=RGBAlphaAND($ffffffff   ,argb($f,$f0,$7f,$07))
   constant RGBOR_TEST1   =RGBAlphaOR($f1f1f1f1   ,argb($8,$8,$8,$8))
   constant RGBXOR_TEST1=RGBAlphaXOR($cccccccc   ,argb($ff,$ff,$ff,$ff))

   print "RGBAND"
   print Hex$(RGBAND_TEST1)
   print "RGBOR"
   print Hex$(RGBOR_TEST1)
   print "RGBXOR"
   print Hex$(RGBXOR_TEST1)

   show()

   
   constant RGBADD_TEST1   =RGBAlphaADD(argb($20,$40,$60,$80),argb($1,$1,$1,$1))
   constant RGBSUB_TEST1   =RGBAlphaSub(RGBADD_TEST1,argb($1,$1,$1,$1))
   constant RGBMULT_TEST1   =RGBAlphaMULT(RGBSub_TEST1,argb($80,$80,$80,$80))

   print "RGBADD FUNCTION"   
   print Hex$(RGBADD_TEST1)

   print "RGBSUB FUNCTION"   
   print Hex$(RGBSUB_TEST1)

   print "RGBMULT FUNCTION"   
   print Hex$(RGBMULT_TEST1)

   Show()
   

   constant RGB_TEST0=rgb($ff,0,0)
   constant RGB_TEST1=rgb(255,0,0)
   constant RGB_TEST2=rgb(0,255,0)
   constant RGB_TEST3=rgb(0,0,255)
   
   print "RGB FUNCTION"   
   Print Hex$(RGB_TEst0)
   Print Hex$(RGB_TEst1)
   Print Hex$(RGB_TEst2)
   Print Hex$(RGB_TEst3)


   print "ARGB FUNCTION"   
   constant ARGB_TEST1=argb(255,0,0,0)
   constant ARGB_TEST2=argb(0,255,0,0)
   constant ARGB_TEST3=argb(0,0,255,0)
   constant ARGB_TEST4=argb(0,0,0,255)

   Print Hex$(ARGB_Test1)
   Print Hex$(ARGB_Test2)
   Print Hex$(ARGB_Test3)
   Print Hex$(ARGB_Test4)


   show()
   





   
   constant Bin_String$ = bin$($ff000000)
   constant Hex_String$ = hex$($ff000000)
   constant ASC_Value    = asc("a")
   constant CHR_String$  = chr$(ASC_VALUE)
   constant Flip_String$  = flip$("Hello World")
   
   Print Bin_String$
   Print Hex_String$
   print ASC_VALUE
   print CHR_STRING$
   print Flip_String$
   Show()


Function Show()

   Sync
   WaitKEY
   waitnokey
   cls
endfunction
   
[/pbcode]


 

 Continued Pre-Solver Improvements...

     I've just finally made my way through all the solver routines, so everything in this regard should be back to normal.  While not the most glamorous topic,  it's been handy casing an eye over some of the oldest code in the parser, it not only performs better now, but a number hidden errors have been trapped as well.  Which is of course is a good thing for everybody.  

[pbcode]

   Constant Dinstance2d_test#=GetDistance2d(100,200,400,500)
   Constant Dinstance3d_test#=GetDistance3d(100,200,400,500,600,700)
   print Dinstance2d_test#
   print Dinstance3d_test#
   a=100
   print GetDistance2d(a,200,400,500)
   print GetDistance3d(a,200,400,500,600,700)
   show()


   Constant Mod_Test1= mod(56, 50)
   Constant Mod_Test2= mod(56.0, 50)
   Constant Mod_Test3= mod(56, 50.0)
   Constant Mod_Test4= mod(56.0, 50.0)

   print Mod_Test1   
   print Mod_Test2   
   print Mod_Test3   
   print Mod_Test4   

   show()

   Constant NewCosValue_Test#=cosnewvalue(100,60,90)
   Constant NewSinValue_Test#=sinnewvalue(100,60,90)
   print NewCosValue_test#
   print NewSinValue_test#

   print cosnewvalue(100,60,90)
   print sinnewvalue(100,60,90)
   Show()


   Constant AlphaBlendRGB_test=RgbAlphaBlend($00ff0000,$000000ff,50)
   print hex$(AlphaBlendRGB_test)

   a=50
   print hex$(RgbAlphaBlend($00ff0000,$000000ff,a))

   show()



   Constant RgbFade_test=RgbFade($ffffff,50)
   print Hex$(RgbFade_test)
   show()

   Constant WrapAngle_test0# = wrapangle(45,15)
   Constant WrapAngle_test1# = wrapangle(45,15.45)
   Constant WrapAngle_test2# = wrapangle(180+180+45)
   print WrapAngle_test0#
   print WrapAngle_test1#
   print WrapAngle_test2#
   a=45
   print wrapangle(a,15.45)
   a=180
   print wrapangle(a+a+45)

   show()

   Constant AtanFull_test# = atanfull(100.34,100)
   print AtanFull_test#
   print atanfull(100.34,100)
   
   
   

   show()   


   Constant CosRadius_test# = cosradius(45,1000)
   Constant SinRadius_test# = sinradius(45,1000)
   print CosRadius_Test#
   print SinRadius_Test#
   show()   


   a#=123.78
   
   Constant Int_test1 = 123.78
   Constant Int_test2 = Int(123.78)

   Print INt_test1
   Print INt_test2

   Constant Float_test1# = 123
   Constant Float_test2# = float(123)

   Print Float_test1#
   Print Float_test2#

   show()   
   


   a#=100.45

   Constant TestAngle#   =100.45

  Constant Root_Test1# =sqrt(100.45)
  Constant Cos_Test#   =cos(TestAngle#)
  Constant Sin_Test#   =sin(TestAngle#)
  Constant Tan_Test#   =tan(TestAngle#)

  Constant aCos_Test#   =acos(Cos_Test#)
  Constant aSin_Test#   =asin(Sin_Test#)
  Constant aTan_Test#   =atan(Tan_Test#)

   print Root_Test1#
   print sqrt(A#)

   print Cos_Test#
   print Sin_Test#
   print Tan_Test#

   print aCos_Test#
   print aSin_Test#
   print aTan_Test#


   a#=45
   print sin(a#)
   print asin(sin(a#))

   show()

   [/pbcode]

  Now onto something a little more interesting..



 PlayBasic V1.64M  Beta 11 Download

  Retails owners can download this beta here..  (old beta deleted)



Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on June 26, 2010, 08:27:53 AM
  PlayBASIC V1.64M  Beta #12 - Mapping Or Sprites Next ?

    The last few days i've been testing with beta #11.  Haven't found anything out of the ordinary with it at this time, but that doesn't mean there isn't.  However, the issue now is what to tackle next in this round up.  Time is getting really away from me and I'm keen to invest my energy where it'll make the most noticeable difference to users.    Which leads us down two paths, Mapping  and Sprites for now.      

    I've been looking at the mapping library most, and like the font library it's missing some robustness with stuff like automatic format conversions, which can cause some of those WTF moments, which i'm very keen to stamp out.  From a usage point of view, there's certainly some need for some more collision / occlusion methods and perhaps rendering methods.    The most horrifying thing about the library though is how it handles level and animation management.  Unlike other parts of the PB, this library has it's own memory manager.  It's quite a robust system, but it's not used globally and given how people use maps in the real world it's largely unnecessary.    

    Since library is old and showing it's age,  it's tempting to remove stuff like the memory manager and give it a real clean up under the hood.   But there's always a risk with this type of change though, in that it will alter the performance or shift the functionality in some unforeseen direction.    Of course, I wouldn't do that unless I thought the benefits outweighed the negatives, there's always a negative!  

    I can probably get away with leaving most of the library the way it is, but it'll need substantial changes to be threaded safely.   Which makes it painful.   The same goes for the sprites actually.  Not the sprite library, but the core filler routines need to be re-written before they can could be made thread safe.    

    What fun...



 Stevmjon's Platformer Being Used For Map Testing

     One of the things i've been writing today though, is a system for rendering AFX map layers (Maps with alpha channel) with background occlusion.  The GFX and map data are by Stevmjon.   The pictures bellow are basically brute force tests.  As such i'm using a much larger resolution than normal (1280*1024*32bit) and just seeing how some cleverly designed code can ease the workload on PlayBASIC's graphics engine, without changing the end visuals.    

    As for how it works,  head over to the  stev's thread (http://www.underwaredesign.com/forums/index.php?topic=3144.msg22753#msg22753)

     
             
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on June 27, 2010, 01:26:05 PM
  PlayBASIC V1.64M  Beta #12 - Mapping Updates

      So far i'm just picking through the mapping library adding in any notable omissions to do with block format conversions.   Which should mean that you can grab blocks what pretty much any surface regardless of the maps format.  

     Bellow we're creating an Video map and grabbing the blocks from an FX surface.

[pbcode]
screen=newimage(800,800)
rendertoimage screen
cls 255
circle 400,400,400,true


BlockWidth=100
BlockHeight=100

Map=Newmap(50)
createmapgfx  Map,BlockWidth,BlockHeight,64,rgb(0,0,255)

Level=NewLevel(Map,8,8)


   For ylp=0 to 7
      For xlp=0 to 7
             Xpos=xlp*BlockWidth
             Ypos=ylp*BlockHeight
            GetMapBlk Map,Tile,Xpos,ypos
            PokeLevelTile Map,Level,xlp,ylp,tile
             inc tile   
       next
   next

   rendertoscreen
   cls $00ff00
   drawmap map,Level,0,0
   print "Video map"
   Sync
   waitkey
   
[/pbcode]


     This example creates an FX map and grabs the tiles from the fx surface.  Which surprisingly wasn't previously possible either.  

[pbcode]


screen=newfximage(800,800)
rendertoimage screen
cls 255
circle 400,400,400,true

BlockWidth=100
BlockHeight=100

Map=Newmap(50)
createmapgfx  Map,BlockWidth,BlockHeight,64,rgb(0,0,255)
preparefxmap map

Level=NewLevel(Map,8,8)


   For ylp=0 to 7
      For xlp=0 to 7
             Xpos=xlp*BlockWidth
             Ypos=ylp*BlockHeight
            GetMapBlk Map,Tile,Xpos,ypos
            PokeLevelTile Map,Level,xlp,ylp,tile
             inc tile   
       next
   next

   rendertoscreen
   cls $00ff00
   drawmap map,Level,0,0
   print "FX map"
   Sync
   waitkey
[/pbcode]

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on June 28, 2010, 12:52:55 PM
  PlayBASIC V1.64M  Beta #12 - Mapping Updates Continued..

    Still ticking away on the mapping library,  Doing some freshening up, while adding the odd bit of new functionality to the library.  Hopefully, closing down those remaining omissions.   One change is the new ability to select the type of blocks being created , when we use the CreateMapGFX command.  This command now has an optional format parameter.  You can select the regular Video, FX , AFX  modes with it.   It's a lot more efficient than the age old solution of creating a video bank of tiles and converting that to FX.      

    For example,  if we create a map with 1024 tiles with a block size 100x by 100 in 32bit.    Then converted this to FX format via PrepareFXmap, then this would takes over 13 seconds to process on my system.   However, if we create the blocks in FX format than grab them, it's all done in 1/2 a second.   Approximately 26 times faster.  

   If we push this further (example code bellow), it'll now handle importing up to 4096 FX tiles in about 1.5 seconds.  In 32bit, that's over 150 meg of gfx data... Not too bad at all...

[pbcode]

t=timer()
screen=newfximage(6400,6400)
rendertoimage screen
boxc 0,0,getsurfacewidth(),getsurfaceheight(),true,$ff0000   
circlec 400,400,400,true,$ffffff

BlockWidth=100
BlockHeight=100

Map=Newmap(50)
createmapgfx  Map,BlockWidth,BlockHeight,4096,$00ff0000,2   ; CREATE 4096 FX BLOCKS

; Makemapgfx  Map,Screen,BlockWidth,BlockHeight,64,$000000ff

Level=NewLevel(Map,GetSurfaceWidth()/BlockWidth,GetSurfaceHeight()/BlockHeight)
leveltransparent Map,Level,200

   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
             ink $ffff00ff
             text Xpos,ypos,Tile
             ink $ffffffff
            GetMapBlk Map,Tile,Xpos,ypos
            PokeLevelTile Map,Level,xlp,ylp,tile
             tile++   
            if Tile=>GetMapBlocks(Map) then exitfor ylp
          next
      endif
   next

tt=timer()-t



   rendertoscreen

   cam=newcamera()
   cameracls cam,off

   c1=rndrgb()
   c2=rndrgb()

Do
   shadebox 0,0,getsurfacewidth(),GetsurfaceHeight(),c1,c1,c2,c2

   capturetoscene   
   clsscene   
   drawmap map,Level,0,0

      speed=2
      if leftkey()    then movecamera cam,-Speed,0
      if rightkey()    then movecamera cam,Speed,0
      if upkey()       then movecamera cam,0,-Speed
      if downkey()    then movecamera cam,0,Speed

      ; displa
   drawcamera cam

   setcursor 0,0   
   print "Built FX map"

   Totalmem=Tile*(BlockWidth*BlockHeight*4)
   print "Memory:"+str$(TotalMem)+"  Bytes   "+str$(TotalMem/(1024*1024))+" Meg"
   print "Ticks:"+STR$(tt)
   Sync
loop

[/pbcode]





Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on June 29, 2010, 08:49:17 AM
  PlayBASIC V1.64M  Beta #12 - Point & Ray Collision Methods

  Here's a couple of new collision tidbits that are on there way to an upgrade near you.   Namely PointHitMapPixels and it's friend ray hit map.   The first function lets us detect if a point (in level space) impacts on a pixel within the map, prolly should be LEVEL...   The other (still testing this) is a way to checking if a ray hits the level at pixel level.  

   Clearly, if we're going to be running pixel level comparison against the block data, then the most optimal format for these is going to be the FX formats, rather than video formats.    The retro method is to use a MASK version of the tiles to run collisions upon.  This way the mask can be tweaked (pixel by pixel).  Running collision against the actually gfx data  (the stuff we see) isn't very common.    You can do much the same thing in PlayBASIC by using two maps.    The masks don't even need to be the same resolution as the original.   Think about it :)  

   Anyway, here's a bit of piccy running pixel level collisions against the map.  

   


[pbcode]

screen=newfximage(6400,6400)
rendertoimage screen
cls $ff0000
circlec 400,400,400,true,$ffffff
circlec 1300,400,400,true,$0fffaf


BlockWidth=100
BlockHeight=100

Map=Newmap(50)
createmapgfx  Map,BlockWidth,BlockHeight,4096,$00ff0000,2   ; CREATE 4096 FX BLOCKS

Level=NewLevel(Map,GetSurfaceWidth()/BlockWidth,GetSurfaceHeight()/BlockHeight)
leveltransparent Map,Level,200

   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
             ink $ffff00ff
             text Xpos,ypos,Tile
             ink $ffffffff
            GetMapBlk Map,Tile,Xpos,ypos
            PokeLevelTile Map,Level,xlp,ylp,tile
             tile++   
            if Tile=>GetMapBlocks(Map) then exitfor ylp
          next
      endif
   next


   rendertoscreen

   cam=newcamera()
   cameracls cam,off

   c1=rndrgb()
   c2=rndrgb()

   Do

      shadebox 0,0,getsurfacewidth(),GetsurfaceHeight(),c1,c1,c2,c2

      MouseWorldXpos=MouseX()-1+GetCameraX(Cam)       
      MouseWorldYpos=MouseY()-1+GetCameraY(Cam)      

      capturetoscene   
      clsscene   

      capturedepth 100

      ; draw the map level
      drawmap map,Level,0,0

      ; DRaw the the Mouse pointer within the world space
      capturedepth 10
      dotc MouseWorldXpos,MouseWorldYpos,RndRGB()


      RayStart=Timer()
      CheckRays(Map,Level,MouseWorldXpos,MouseWorldYpos,300,64)
      RayTime=Timer()-RayStart
      
      ; draw whatever the camera can see
      drawcamera cam

      setcursor 0,0         
      
      ink $ff0000ff

      print "Ray Timer:"+STR$(RAYTIME)
      

         speed=2
         if leftkey()    then movecamera cam,-Speed,0
         if rightkey()    then movecamera cam,Speed,0
         if upkey()       then movecamera cam,0,-Speed
         if downkey()    then movecamera cam,0,Speed

      Sync
   loop




Function CheckRays(Map,Level,Xpos,Ypos,RAdius,Rays)
      AngleStep#=360.0/Rays

         For lp=0 to rays-1
               angle#=lp*AngleStep#
               x2#=cosnewvalue(xpos,Angle#,radius)
               y2#=sinnewvalue(ypos,Angle#,radius)
               Collision=RayHitMapPixels(Map,Level,xpos,ypos,x2#,y2#)
                if Collision
                      hitx#=getINtersectx#(0)
                      hity#=getINtersecty#(0)
                      line xpos,ypos,hitx#,hity#
                      circlec hitx#,hity#,5,true,$00ff0000   
               else
                  line xpos,ypos,x2#,y2#
               endif
         next   
      

EndFunction


[/pbcode]



 Download

 [plink]Get V1.64M Beta #12 (http://www.underwaredesign.com/forums/index.php?topic=1150.msg22763#msg22763) [/plink]


 
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on July 03, 2010, 04:45:46 PM
  PlayBASIC V1.64M  Beta #13 - Map Spring Cleaning

  Spent the last couple of days doing something of a winter clean (it's winter here BTW)  of the core mapping commands, focusing upon the Block creation commands.   Found a number of little annoying tidbits while picking through it and have been able to reduce the foot print of the code just by better structure.  So that's a win! -  So far i've resisted the urge the remove the libraries memory manager (a first! :) ),  even thought i really, really want too ! :) - However, I can see some good opportunities for commands to help communication between programmers and the library a little better.    

  For example,  it'd be handy if the map library would import/export  a level to a  2D array.  Another thing that would in useful would an optional parameter on the PeekLevelTile function, to request the command resolve any animation peeks to the Block Index.

  I've got a number of ideas for rendering tweaks (and commands to help reduce rendering), but you'll have to wait and see on that one.



 PlayBASIC V1.64M  Beta #13 - Debugger - View Programs Memory Consumption

   This is a bit of kick back to the original debugger 'to do' list from years ago.  Which is a feature to give the user some idea of the amount of memory their program is using.    To do that, I've got to run through and query each command set.   So I decided to make a report out of it since it's not something you want to be doing real time.

   So basically this new feature allows us to dump the 'state' of the running program to the console as a text report.   The report,  allows us to look at the core libraries contain, so we can  get an idea of the overall applications resource usage and it's memory consumption at that time.  

   The report is nothing fancy, just simple text  dropped to the debugger console. It's broken up into sections, each section covers the state of the media within the command set with an approximation the memory consumption at the and of each section.  The report concludes with the tallied memory consumption.  

   Estimates ? - Yes, while the values are indeed accurate,  the calculation routine doesn't and can't see the fine details of the command sets from the debugger.   So the values returned are basically slight under estimates.  If it reports the program is using 100 meg, than that's a certainty! - However,  internally the engine might be using another couple of the meg for temp data.    So i'd suggest adding %5 to %10 to whatever values it returns.

   This feature should take the guess work out of recommending the system requirements for your completed games.  

  Here's an example of the report.  



[==================== START PROGRAM MEMORY USAGE ======================]


------------------------------------------------------------------------------------------------------------
[SCREEN SYSTEM]
------------------------------------------------------------------------------------------------------------
[
SCREEN #0
[
Width =1024
Height =768
Depth =32
]

Screen.Video Memory Usage =6291456 Bytes
Screen.System Memory Usage =80 Bytes
]




------------------------------------------------------------------------------------------------------------
[FONT SYSTEM]
------------------------------------------------------------------------------------------------------------
[
FONT #1
[
Name =Courier
Type =1 Windows GDI
ChrWidth =8
ChrHeight =13
]

Fonts.Video Memory Usage =0 Bytes
Fonts.System Memory Usage =98055 Bytes
]




------------------------------------------------------------------------------------------------------------
[IMAGE SYSTEM]
------------------------------------------------------------------------------------------------------------
[
IMAGE #1
[
Name =
Type =2 [FX]
Width =6400
Height =6400
Depth =32
Mask =00000000 A=0 R=0 G=0 B=0
]

Images.Video Memory Usage =0 Bytes
Images.System Memory Usage =163942000 Bytes
]




------------------------------------------------------------------------------------------------------------
[SPRITE SYSTEM]
------------------------------------------------------------------------------------------------------------
[
Sprite.System Memory Usage =336000 Bytes
]




------------------------------------------------------------------------------------------------------------
[MAP SYSTEM]
------------------------------------------------------------------------------------------------------------
[
MAP #1
[
Map(1).Blocks
[
Width =100
Height=100
Count=1024
]

Map(1).Level Quantity=50
[
Map(1).Level (0)
[
Width    =64
Height   =64
Drawmode =2
]

]

Map(1).Animation Quantity=20
[
Map(1).Anim (5)
[
Type   =1
CurrentFrame =0
Frames   =50
Sequence =-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
]
]

]

Maps.Video Memory Usage =0 Bytes
Maps.System Memory Usage =29676 Bytes
]




------------------------------------------------------------------------------------------------------------
[MEMORY CONSUMPTION SUMMARY]
------------------------------------------------------------------------------------------------------------
[
Program.Total Video Memory Usage =6 Megabytes (6291456) Bytes.
Program.Total System Memory Usage =156 Megabytes (164069811) Bytes.
]



[==================== END PROGRAM MEMORY USAGE ======================]










Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on July 05, 2010, 02:42:59 PM
  PlayBASIC V1.64M  Beta #14 - Debugger Cont..

  Haven't had that much hands on PlayBASIC time in the last couple of days, so i've only been doing the odd programming session here and there.  Mostly cleaning up some of the content output routines in the debugger. So it's formatting the text up a little better now.   Added the odd extra bit of info here and there, so it's easier to see what's going on..  

  Also been having a look see at the array dump routines trying to the write a quicker routine to dump the typed array state.   Lots of string and memory thrashing, so it can be pretty slow when look at the big arrays..  Could possibly give a warning when viewing really large one's as the it becomes a huge amount of the data..



 Edit: A few hours later

    As mentioned previously, i've been tweaking the array conversion to string functions, this process could really bog down on large typed arrays.  How much ? -  Well, in V1.64M Beta 12, if I run the code bellow and click upon the typed array in the debugger/variable view.  It takes a little over 4 minutes to dump the whole array to a string representation.    This same process only takes a couple of seconds in V1.64M Beta14  


[pbcode]
   Type Test   
      b as byte
      w as word
      I
      F#
      s$
      Ia(10)
      Fa#(10)
      Sa$(10)
   Endtype

   print sizeof(Test)

   max=10000
   DIm Cool(max)
   DIm Cool#(max)
   DIm Cool$(max)
   DIm CoolTyped(max) as test

t=timer()
   for lp=0 to max
      Cool$(lp)="TEST"+str$(lp)
      CoolTyped(lp).s$ ="Test"+Str$(lp)
   next
t=Timer()-t
   print t
   Sync
   WaitKey
[/pbcode]




   
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on July 08, 2010, 11:25:00 AM
  PlayBASIC V1.64M  Beta #14 - MakeMapGFX

    Back tapping away at the guts of the mapping library.  Adding the odd optional parameter here and there and embedding from new functionality where I can and where it makes sense.    Previously i mentioned using a two maps, one for the display and one for collision.   Obviously the mask version doesn't need as many tiles, sow e can save memory by reducing the block set down.   However the block depth is still coming from whatever the depth of the screen is, unless we're loading (or making block from) an AFX surface.  In which case the blocks will always be 32bits deep.   But we really don't need alpha for the mask, since we never see it.  So to conserve memory i've add the ability to set the FX maps surface depth.      

    Using the example above, if we have 4096 blocks (100*100),  in 32bit that's around 156 meg of memory.   However, we can save 50% of that by using 16bit blocks for the map  data.    Which is likely (haven't checked) to aid in collision detection against the map.

  The example above creates the same boring scene as before, expect this time it forces PB to create 16bit blocks for the map data.



[pbcode]

   BlockWidth=100
   BlockHeight=100


   screen=1
   sync

    screen=newfximage(6400,6400)
; createfximageex screen,6410,6400,16
; createfximage screen,6400,6400

    rendertoimage screen

   TilesX=GetSurfaceWidth()/BlockWidth
   If (TilesX*BlockWidth)<GetSurfaceWidth() then TilesX++

   TilesY=GetSurfaceHeight()/BlockHeight
   If (TilesY*BlockHeight)<GetSurfaceHeight() then TilesY++

; boxc 0,0,getsurfacewidth(),getsurfaceheight(),true,$ff0000   
    cls $f00000
    circlec 400,400,400,true,$ff80ff
    circlec 1300,400,400,true,$0080ff

; Number the blocks
   Tile=0
   For ylp=0 to tilesy-1
      Ypos=ylp*BlockHeight
      For xlp=0 to tilesX-1
         Xpos=xlp*BlockWidth
         ink $8fff00ff
         text Xpos,ypos,Tile
         ink $ffffffff
         Tile++
       next
   next



;rendertoscreen

   t=timer()

   Map=Newmap(50)
;   createmapgfx  Map,BlockWidth,BlockHeight,4096,$f00000, 2 ;or lsl32(15,16)   ; CREATE 4096 FX BLOCKS

   MakeMapGFX  Map,Screen,BlockWidth,BlockHeight,4096,$00f00000,2 or lsl32(15,16)

   Level=NewLevel(Map,GetSurfaceWidth()/BlockWidth,GetSurfaceHeight()/BlockHeight)
   leveltransparent Map,Level,200


   ; Create the level data to represent this the original image.
   Tile=0
   For ylp=0 to tilesy-1
      Ypos=ylp*BlockHeight
      if Ypos+BlockHeight<=GetSurfaceHeight()
          For xlp=0 to tilesX-1
             if Tile=>GetMapBlocks(Map) then exitfor ylp
;            GetMapBlk Map,Tile,Xpos,ypos
            PokeLevelTile Map,Level,xlp,ylp,tile
             tile++   
          next
      endif
   next



   MapAnimQuantity Map,20
   CReateMapAnim Map,5,50

tt=timer()-t


   rendertoscreen

   cam=newcamera()
   cameracls cam,off

   c1=rndrgb()
   c2=rndrgb()

   Do

      cls $00ff00

      MouseWorldXpos=MouseX()-1+GetCameraX(Cam)       
      MouseWorldYpos=MouseY()-1+GetCameraY(Cam)      

      CaptureToScene   
      ClsScene   
      CaptureDepth 100

      ; draw the map level
      DrawMap map,Level,0,0


      ; draw whatever the camera can see
      drawcamera cam


      if rightmousebutton()
            EndX=MouseWorldXpos
            EndY=MouseWorldYpos
      endif

      setcursor 0,0         
      
      ink $ff0000ff

      Totalmem=Tile*(BlockWidth*BlockHeight*2)

      Print "Memory:"+str$(TotalMem)+"  Bytes   "+str$(TotalMem/(1024*1024))+" Meg"
      Print "Ticks:"+STR$(tt)



         speed=2
         if leftkey()    then movecamera cam,-Speed,0
         if rightkey()    then movecamera cam,Speed,0
         if upkey()       then movecamera cam,0,-Speed
         if downkey()    then movecamera cam,0,Speed

      Sync
   loop



[/pbcode]




Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on July 09, 2010, 03:38:13 PM
  PlayBASIC V1.64M  Beta #14


     Here's the latest work in progress of the PlayBASIC V1.64M upgrade.    The changes mostly focuses on improving the Mapping library and some new features for the run time Debugger.  All that stuff is covered above..


 DOWNLOAD

  [plink]Download PlayBASIC V1.64M Beta14 (http://www.underwaredesign.com/forums/index.php?topic=1150.msg22804#msg22804) [/plink]



Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on July 12, 2010, 11:31:53 AM
  PlayBASIC V1.64M  Beta #14 - FlexiGUI Testing

    The past couple of days have been all about beta testing. For this session i've been using the FlexiGUI library (since it's huge).   The library was written some 5 years ago and it shows, so it's not really representative of the feature set of PlayBASIC today.  But there's not too much I can do about that really, as I'm just knocking up some usage examples to help newcomers wrap their minds around it.     There will be a tutorial to go with this, but that's about it for now.

    The following picture is of one of the examples.  It's showing how users can manage many windows, each with their own unique gadgets.   Understanding the  management  really comes down to how well you understand TYPES though.   So for those you've been putting off learning about TYPES, then there's no time like the present.  


   Edit

      Still tinkering around with some flexi examples. The last screenie (bellow) uses the LABEL, SCROLLERS and PICTUREBOX gadgets together.  It's set up to display a scaled picture (randomly) in the current window.  The user can scale it using the scrollers.  The only thing tricky about it, is you've got to careful when n refreshing the PICTUREBOX gadget.  The GADGET has it's own surface and the picture your displaying.  If you Render to the Gadget, then you're actually drawing to gadgets surface and not the picture you attached.    That one even had me stumped for a while :)...   


Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on July 15, 2010, 12:43:26 PM
  PlayBASIC V1.64M  Beta #14 - Minor Update For FlexiGUI

     Been working on the GUI tutorial most of the day, what fun :(... Anyway, previously I mentioned that due to the age of the library, it's missing some of the newest compiler & command set (graphical) features.   So i've taken this brief opportunity to tweak the code up a bit.   The main changes to the library  so far would be the addition some  optional parameters/wrapper functions plus  support for  dynamic function calling.   Two subtle changes, that make make some interesting things possible.

    The dynamic function calling allows us to make the flexi main loop that little bit simpler upon the programmer.   In older versions of the library, the user manages events by calling the libraries event update function, then looping through and catching any user event. Once that's done we reset the event stack for the next update.   This process is still how the library works, we can reduce the code to single function call.    All we have to do is write a function to process the user event we want to handle,  then tell the Flexi what this function is called.    When we call the FlexiUpdate() function it gets user input/processes the SYSTEM AND USER events and reset the event stack for the next frame.  

    So Inside FlexiUpdate function, the library is dynamically calling the users event handler.    A small change, but one that'll help clean up the handling and encourage people to more away from single scope programs to a more function based design.  


   Another new feature is the ability to create a window and nominate the type of the image buffer this window will use.  By default the library creates images in Video memory, but now we can force them to be FX or AFX even (untested !).  If you create an FX Window then any gadgets will inherit this state also.  Which means you can use a micture of surface types.   Useful if you need to do blending in a window.


   Bellow is one of the examples from the Flexi Example pack.. It shows some of the new design features.  I'm tempted to the expand the FlexiUPDATE() function a little more.   For example, you could just pass the function the name of the your handler, as well as some parameters to tell it to render the scene also.    I know this might sound tempting to some people to make that how it works, but forcing such behavior would make programming other interactions with the gui scene awkward..  Like drawing your own stuff in side the scene.

[pbcode]

; *=-----------------------------------------------------------------=*
;
;                      >> Flexi (GUI) Example #6 <<
;
;                           By Kevin Picone            
;
;         (c) copyright 2010 by Kevin Picone, All Rights Reserved
;
; *=-----------------------------------------------------------------=*
;         www.underwaredesign.com   -   www.PlayBasic.com
; *=-----------------------------------------------------------------=*
;
;    In this example we're going to add the task bar to the previously demo.
; The task bar is basically a docking bar for minimized windows.  Normally
; if we minimize a window, the window is no longer drawn. SO it's hidden,
; except when task bar is active. Now when we minimize the the window will
; auto dock on the bar.   You to restore the window by clicking it's name
; on the task bar.  
;
;    If you run the example you'll see the task bar across the bottom of the
; screen.  If you click a minimize gadget on a window, it's NAME will appear
; on the bar.
;  
; *=-----------------------------------------------------------------=*

      ; ---------------------------------------
      ; Include the GUI library in our program
      ; ---------------------------------------
      #include "FlexiGUI"
      

      ; ---------------------------------------
      ; Create & Set up our window.
      ; ---------------------------------------
      
         ; create the task bar window. This window will hold minized
         ; windows for use.      
         TaskBarWindow=FlexiCreateTaskBar()
      
      
         ; create an array that'll hold our ten windows for this example
            Dim Windows(10)

            For lp=1 to 10
   
               ; create a window that's a random width and height
                  Width=RndRange(100,500)
                  Height=RndRange(100,500)
                  Title$="I'm Window #"+Str$(lp)
                  ThisWindow   = FlexiCreateWindow(Width,Height,title$)               


               ; Set the position of this window to random location on screen
                  Xpos=RndRange(0,GetScreenWidth()-width)
                  Ypos=RndRange(0,GetScreenHeight()-Height)
                  FlexiPosition(ThisWindow,Xpos,Ypos)

                  
               ; Tell flexi to open the window. This initializes the window
               ; (and any attached gadgets) for drawing.
                  FlexiOpen(ThisWindow)

               ; Store the Handle of the thisWindow in our Windows array
               ; so we can remember them later on.
                  Windows(lp)=ThisWindow   

            next

            ; tell Flexi What function to call when it see's
            ; a user event during FlexiUpdate() function
            FlexiSetUserEventhandler "User_Event_Handler"

      ; ---------------------------------------
      ; Program Main Display Loop
      ; ---------------------------------------

      setfps 60

   
      Do

         ; Clear the screen to the default colour black (rgb(0,0,0))
            cls       

         ; Call the FlexuUpdate to get user input, process SYSTEM and USER
         ; events.
            FlexiUpdate()
            
         
         ; redirect all rendering back to the screen
            rendertoscreen

         ; Call the Flexi Render Function to draw the GUI windows
            FlexiRender()      
      
      
         ; Call sync to show the drawn screen to the user
            Sync

      loop esckey()=true


      ; Tell PlayBASIC To END
      end




Function User_Event_Handler(EventIndex)


         ; Read what GUI Object this event came from
         ThisObject=FlexiEvents(EventIndex).ThisObject


         ; Read the type of event  
            Select FlexiEvents(EventIndex).EventType

                  ; Catch the various USER events.  A user event is an
                  ; event the GUI expects the USER to take care of.

                  ; -------------------------------------
                  case FlexEvent_UserOpenWindow
                  ; -------------------------------------
                     ; Run through and find what Window posted this event
                     ; When we find it, we call the DRaw_Main_Window() function.
                     ; this will initialize the windows graphics content for us.
                     ; So the windows will all have the shade box with the
                     ; HELLO WORLD in the center of them.
                     For lp=1 to Getarrayelements(Windows())
                        if ThisObject=Windows(lp)   
                              Draw_Main_window(ThisObject)
                        endif         
                     next

                  ; -------------------------------------
                  case FlexEvent_UserCloseWindow
                  ; -------------------------------------
                     ; The user Clicked the CLOSE Gadget, so here we'll remove
                     ; this Window Handle from our Windows() array.
                     For lp=1 to Getarrayelements(Windows())
                        if ThisObject=Windows(lp)   
                              ; remove this flexi window
                              FlexiDelete ThisObject
                              ; delete this cell within the array
                              Windows(lp)=0
                        endif         
                     next



                  ; -------------------------------------
                  case FlexEvent_UserWindowFocus
                  ; -------------------------------------

                  ; -------------------------------------
                  case FlexEvent_UserMaxiMized
                  ; -------------------------------------

                     ; Check What GUI object was being maximized ?
                     ; was it our main window ?- If so, clear the window
                     ; and render some text on it.

                     For lp=1 to Getarrayelements(Windows())
                        if ThisObject=Windows(lp)   
                              Draw_Main_window(ThisObject)
                        endif         
                     next
                  
                  ; -------------------------------------
                  case FlexEvent_UserMiniMized
                  ; -------------------------------------

                  ; -------------------------------------
                  case FlexEvent_UserRedraw
                  ; -------------------------------------


                  ; -------------------------------------
                  case FlexEvent_UserResize
                  ; -------------------------------------
                     ; check if our window was resized ?
                     For lp=1 to Getarrayelements(Windows())
                        if ThisObject=Windows(lp)   
                              Draw_Main_window(ThisObject)
                        endif         
                     next

                  case FlexEvent_UserResizeInProgress
                  case FlexEvent_UserMouseClick
                  case FlexEvent_UserMouseOver
                  case FlexEvent_UserKeyStroke
                  case FlexEvent_UserHitEnter
                  case FlexEvent_Vscroll_Change
                  case FlexEvent_Hscroll_Change
                  
               EndSelect

EndFunction



Function Draw_Main_window(ThisWindow)
   
         ; Redirect All Rendering to this WINDOW               
         flexirenderto ThisWindow


         ; Get the Size of the render area of this window
            x1,y1,x2,y2=FlexiGetViewport(ThisWindow)

            Width=x2-x1
            Height=y2-y1

         ; clear it to a RED/PurPle colour
            c1=rgb(200,0,100)
            c2=rgb(50,20,60)
            shadebox x1,y1,x2,y2,c1,c1,c2,c2

         ; Set the ink colour.  You never know what it was before
         ; this function was called
             ink argb(255,255,255,255)

         ; draw the message on it
            centertext Width/2,Height/2, "HELLO WORLD"
EndFunction


[/pbcode]

   

 PlayBASIC V1.64M  Beta #14 -  FlexiGUI Window Alpha Level

   The attached picture show Window Alpha control, which is by product of the ability of creating FX windows.  So we create FX surface, then draw the Gui onto it.. hey presto alpha.

   See Alpha Windows Demo (http://www.youtube.com/watch?v=hOpJrpm9JLM) on youtube.

 




Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on July 16, 2010, 01:00:26 PM
  PlayBASIC V1.64M  Beta #14 - FlexiGUI Possible Event Attachments ?

     One of the big features additions to PB in the last year, has been the ability to call functions/psubs dynamically.  This is one of those features that is used to overcome very specific problems.    A common one occurs where we have to write  dispatch style routines, where the code is working out what function to call from a hard code list of options.    If such a problem occurs, you could use CallFunction to look up the function to call and then just react to it.   the interesting thing about this version of the dispatch routine is that we don't really have to update it when we add more possible options, like we would if using a Select/Case state or if/thens

    I mention this, as when programming a GUI based application, a lot of the code goes into working out what GUI element the user interacted with and then calling our reaction code.   Now some high level languages address this for the user, but they're often specifically built to hide this process away from the programmer.  So it's building it's own dispatch routines underneath.  Where we have a routine that gets the event and calls the handler for us.   We can't really do this is PB today, but we could do something similar.  By setting up some way of attaching the reaction code, during the creation process.  

    Imagine if you create a window,  then Flexi places the UserCreateWindow event on the event stack.  We can then react to it this event during our event processing loop.  But what if we could do attach some generic handlers to the window when  creating it.   Which could look something like this.

  (Sample Only)

[pbcode]
    MyWindow=FlexiCreateWindow(width,height,title$)

    Event$ ="CreateWindow=FunctionToHandleThis"
    Event$ ="ONLick=FunctionToHandleThis"
    Event$ ="ResizeWindow=FunctionToHandleThis"
    Event$ ="Redraw=FunctionToHandleThis"

    MyWindow=FlexiAttachEventHandlers(MyWindow,Event$)

[/pbcode]

 
  The idea being that we could setup what functions (if any) FLEXI calls when a certain event is processed.     Now, we're not really saving ourselves much code here.  We're opening up the door making the program code more generic.   So we can drop in new functionality and not have to maintain the overall event processing ourselves.    Although, I suspect there would be times where that would be favorable.    But we'll see how it goes..



 PlayBASIC V1.64M  Beta #14 - FlexiGUI Now Supports Attachable Event Handler
   
     Well, in a few hours this idea has gone from one of those "wouldn't it be nice things" to brand new feature of the FlexiGUI library.    As suggested above, the library lets users attach their own event handler functions to FlexiGUI  WINDOWS or GADGETS.    This is done in two ways, you can either attach each and every handler individually (using a function called FlexiAddEventHandler() ) or you can prepare a string with the event name and the function names they each call in them.     The latter is probably the easier of the two.  The event names are the same as the event constants.  Without the 'FlexEvent_User' part.    

      Here's what the event attachment part looks like when you build the event list string and attach it to a window.  

[pbcode]

               ; Create the Event Handler string, this string is parsed by
               ; flexi.  The string contains the event name and the function
               ; that should be called when that user event occurs.

                  Event$  ="OpenWindow & Resize &   Maximize   =Draw_Window_EventHandler,"
                  Event$ +="CloseWindow                  =Delete_Window_EventHandler"

                  FlexiParseEventHandlerList(ThisWindow,Event$)


[/pbcode]


   This bit of code traps 4 different events from this window.  Those being OpenWindow, Resize, Maximize and CloseWindow.   The first three event all trigger the same handler function, which is the Draw_Window_EventHandler.   You provide this function for the purpose of drawing the window.   The other event is CloseWIndow, that one calls the Delete_Window_EventHandler function.   So when the user clicks [ X ] button,  Flexi calls  your deleter during the next event update loop.    All of which occurs virtually transparently to the user.  

    Here's the revised version of the Example #6 (compare older version in previous post).   The new version is certainly shorter and hopefully a bit easier for new comers to get up and running.  


[pbcode]

; *=-----------------------------------------------------------------=*
;
;               >> Flexi (GUI) Example #6 (Event Handler Version) <<
;
;                           By Kevin Picone            
;
;         (c) copyright 2010 by Kevin Picone, All Rights Reserved
;
; *=-----------------------------------------------------------------=*
;         www.underwaredesign.com   -   www.PlayBasic.com
; *=-----------------------------------------------------------------=*
;
;    In this example we're going to add the task bar to the previously demo.
; The task bar is basically a docking bar for minimized windows.  Normally
; if we minimize a window, the window is no longer drawn. SO it's hidden,
; except when task bar is active. Now when we minimize, the window will
; auto dock on the bar.   You can restore the window by clicking it's name
; on the task bar.  
;
;    If you run the example you'll see the task bar across the bottom of the
; screen.  If you click a minimize gadget on a window, it's NAME will appear
; on the bar.
;  
; *=-----------------------------------------------------------------=*

      ; ---------------------------------------
      ; Include the GUI library in our program
      ; ---------------------------------------
      #include "FlexiGUI"
      

      ; ---------------------------------------
      ; Create & Set up our window.
      ; ---------------------------------------
      
         ; create the task bar window. This window will hold minized
         ; windows for use.      
         TaskBarWindow=FlexiCreateTaskBar()
      
      
         ; create an array that'll hold our ten windows for this example
            Dim Windows(10)

            For lp=1 to 10
   
               ; create a window that's a random width and height
                  Width=RndRange(100,500)
                  Height=RndRange(100,500)
                  Title$="I'm Window #"+Str$(lp)
                  ThisWindow   = FlexiCreateWindow(Width,Height,title$)               


               ; Set the position of this window to random location on screen
                  Xpos=RndRange(0,GetScreenWidth()-width)
                  Ypos=RndRange(0,GetScreenHeight()-Height)
                  FlexiPosition(ThisWindow,Xpos,Ypos)

                  
               ; Tell flexi to open the window. This initializes the window
               ; (and any attached gadgets) for drawing.
                  FlexiOpen(ThisWindow)

               ; Store the Handle of the thisWindow in our Windows array
               ; so we can remember them later on.
                  Windows(lp)=ThisWindow   

               ; Create the Event Handler string, this string is parsed by
               ; flexi.  The string contains the event name and the function
               ; that should be called when that user event occurs.

                  Event$  ="OpenWindow&Resize&   Maximize   =Draw_Window_EventHandler,"
                  Event$ +="CloseWindow                  =Delete_Window_EventHandler"

                  FlexiParseEventHandlerList(ThisWindow,Event$)

            next


      ; ---------------------------------------
      ; Program Main Display Loop
      ; ---------------------------------------

      setfps 60


      Do

         ; Clear the screen to the default colour black (rgb(0,0,0))
            cls       

         ; Call the FlexuUpdate. This function collects user and
         ; processed SYSTEM and USER events.
            FlexiUpdate()
            
         ; redirect all rendering back to the screen
            rendertoscreen

         ; Call the Flexi Render Function to draw the GUI windows
            FlexiRender()      
      
         ; Call sync to show the drawn screen to the user
            Sync

      loop esckey()=true

      ; Tell PlayBASIC To END
      end



Function Delete_Window_EventHandler(ThisWIndow,EventIndex)

      ; The user Clicked the CLOSE Gadget, so here we'll remove
      ; this Window Handle from our Windows() array.
         For lp=1 to Getarrayelements(Windows())

               if ThisWindow=Windows(lp)   
                     ; remove this flexi window
                     FlexiDelete ThisWindow
                     ; delete this cell within the array
                     Windows(lp)=0
               endif         
         next

EndFunction


Function Draw_Window_EventHAndler(ThisWindow,EventIndex)

         ; Redirect All Rendering to this WINDOW               
         flexirenderto ThisWindow

         ; Get the Size of the render area of this window
            x1,y1,x2,y2=FlexiGetViewport(ThisWindow)

            Width=x2-x1
            Height=y2-y1

         ; clear it to a RED/PurPle colour
            c1=rgb(200,0,100)
            c2=rgb(50,20,60)
            shadebox x1,y1,x2,y2,c1,c1,c2,c2

         ; Set the ink colour.  You never know what it was before
         ; this function was called
             ink argb(255,255,255,255)

         ; draw the message on it
            centertext Width/2,Height/2, "HELLO WORLD"
EndFunction

[/pbcode]

  Attached is piccy of the example running.  As you can see, it gives a simple scene made up of a group of unique windows.




 
 
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on July 19, 2010, 04:31:30 PM
  PlayBASIC V1.64M  Beta #14 - Screen Support for  FlexiGUI


    Up till now Flexi has supported two basic types of elements,  WINDOWS and GADGETS.   Each element has various types.    However, the original source includes the start of (but not fleshed out) support for a third type called a screen.  If memory serves me correctly this was to represent the PB screen within the GUI environment.   Clearly it was deemed as future since it's wasn't implemented.   After playing the library a bit over the past week, there's certainly need for such a control.

    What the SCREEN does is it lets us create a window that presents the PB display screen.  The main advantage of this is that we can now react to user clicks & key strokes upon the screen surface.  For example, if you wanted to draw on to the screen with the mouse, then previously you'd have to work out if the mouse is over a Flexi window, is it dragging a window ?  etc etc.   No longer, now we just create the Screen window and the  attach the message handlers to react to user clicks.   So the GUI does the work for us.

    In this example i've add the screen window to the existing example.  The screen reacts to the click events, so when a click occurs, FlexiUpdate calls our Mouse Click function.   Which in this cases draw a randomly coloured circle upon the Screen window.  

[pbcode]


; *=-----------------------------------------------------------------=*
;
;               >> Flexi (GUI) Example #6 (Event Handler Version) <<
;
;                           By Kevin Picone            
;
;         (c) copyright 2010 by Kevin Picone, All Rights Reserved
;
; *=-----------------------------------------------------------------=*
;         www.underwaredesign.com   -   www.PlayBasic.com
; *=-----------------------------------------------------------------=*
;
;    In this example we're going to add the task bar to the previously demo.
; The task bar is basically a docking bar for minimized windows.  Normally
; if we minimize a window, the window is no longer drawn. SO it's hidden,
; except when task bar is active. Now when we minimize, the window will
; auto dock on the bar.   You can restore the window by clicking it's name
; on the task bar.  
;
;    If you run the example you'll see the task bar across the bottom of the
; screen.  If you click a minimize gadget on a window, it's NAME will appear
; on the bar.
;  
; *=-----------------------------------------------------------------=*

      ; ---------------------------------------
      ; Include the GUI library in our program
      ; ---------------------------------------
      #include "FlexiGUI"
      

      ; ---------------------------------------
      ; Create & Set up our window.
      ; ---------------------------------------
      
         ; create the task bar window. This window will hold minimized
         ; windows for us.      
            TaskBarWindow=FlexiCreateTaskBar()
      
         ; create an array that'll hold our ten windows for this example
            Dim Windows(10)

            For lp=1 to 10
                  New_window()
            next


         Screen=FlexiCreateScreen()   
         FlexiOpen(Screen)
         Event$  ="Mouseclick=ClickScreen"
         FlexiParseEventHandlerList(Screen,Event$)

      
      ; ---------------------------------------
      ; Program Main Display Loop
      ; ---------------------------------------

      setfps 60


      Do

         ; Clear the screen to the default colour black (rgb(0,0,0))
;            cls       

         ; Call the FlexuUpdate. This function collects user input then
         ; processes SYSTEM and USER events.
            FlexiUpdate()
            
         ; redirect all rendering back to the screen
            rendertoscreen

         ; Call the Flexi Render Function to draw the GUI windows
            FlexiRender()      
      
         ; Call sync to show the drawn screen to the user
            Sync

      loop esckey()=true

      ; Tell PlayBASIC To END
      end





Function Delete_Window_EventHandler(ThisWIndow,EventIndex)

      ; The user Clicked the CLOSE Gadget, so here we'll remove
      ; this Window Handle from our Windows() array.
         For lp=1 to Getarrayelements(Windows())

               if ThisWindow=Windows(lp)   

                     New_window()

                     ; remove this flexi window
                     FlexiDelete ThisWindow
                     
                     ; delete this cell within the array
                     Windows(lp)=0
               endif         
         next

EndFunction


Function Draw_Window_EventHAndler(ThisWindow,EventIndex)

         ; Redirect All Rendering to this WINDOW               
         flexirenderto ThisWindow

         ; Get the Size of the render area of this window
            x1,y1,x2,y2=FlexiGetViewport(ThisWindow)

            Width=x2-x1
            Height=y2-y1

         ; clear it to a RED/PurPle colour
            c1=rgb(200,0,100)
            c2=rgb(50,20,60)
            shadebox x1,y1,x2,y2,c1,c1,c2,c2

         ; Set the ink colour.  You never know what it was before
         ; this function was called
             ink argb(255,255,255,255)

         ; draw the message on it
            centertext Width/2,Height/2, "HELLO WORLD"
EndFunction



Function New_window()

            ; Find a free position with this array
               Index=getfreecell(Windows())
      
            ; create a window that's a random width and height
                  Width=RndRange(100,500)
                  Height=RndRange(100,500)
                  Title$="I'm Window #"+Str$(Index)
                  ThisWindow   = FlexiCreateWindow(Width,Height,title$)               


               ; Set the position of this window to random location on screen
                  Xpos=RndRange(0,GetScreenWidth()-width)
                  Ypos=RndRange(0,GetScreenHeight()-Height)
                  FlexiPosition(ThisWindow,Xpos,Ypos)

               ; Tell flexi to open the window. This initializes the window
               ; (and any attached gadgets) for drawing.
                  FlexiOpen(ThisWindow)

               ; Store the Handle of the thisWindow in our Windows array
               ; so we can remember them later on.
                  Windows(Index)=ThisWindow   

               ; Create the Event Handler string, this string is parsed by
               ; flexi.  The string contains the event name and the function
               ; that should be called when that user event occurs.

                  Event$  ="OpenWindow&Resize&   Maximize   =Draw_Window_EventHandler,"
                  Event$ +="CloseWindow                  =Delete_Window_EventHandler"

                  FlexiParseEventHandlerList(ThisWindow,Event$)


EndFunction




Function ClickScreen(ThisObject,EventIndex)
   
      ; redirect all drawnig to the GUI elements surface
      FlexiRenderTo ThisObject

      ; Draw a circle onto this surface.
      circlec mousex(),mousey(),100,true,rndrgb()

EndFunction



[/pbcode]



   
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on July 30, 2010, 01:02:16 AM
   PlayBASIC V1.64M  Beta #16 - Download

    The latest beta of the V1.64M upgrade is on the server and ready for testing..  
       

 Download

   deleted
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on August 29, 2010, 09:20:38 PM

  PlayBASIC V1.64M  Beta #17 - Build Process Hiccups

     With most of the recent headaches seemingly out of the way for the time being,  my focus is shifting back to V1.64M.   First port of call is to update the runtime build process. Unfortunately the cascading issues a few months back, have meant that the runtime builder is now incapable of creating working runtimes. 

    So  this morning i've been working my way through the issues,  which is a slow and tedious process.  Some progress is being made though, as the current version now boots without crashing (always a plus) , but it halts soon after with inexplicable fault.   Which just means more good old fashion tracing to find it...  I do feel like the back of the problem has been broken though, and can't imagine this persisting beyond tomorrow.   But you never know :)

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on August 30, 2010, 11:44:15 PM

    PlayBASIC V1.64M  Beta #18 - Running Runtimes Again

           Took a bit longer than i'd hoped but the Vm builder can once again build the working runtimes.  Most of the issues were fairly easy to pickup, but the main problem turned out to the be a situational issue with the replacement string library function.    Which would stop t5he built runtime dead in it's tracks.   But both version are now up an running again. So we work towards a release build (the actual upgrade version).  However I feel it's probably best to beta this prior to that.  Since making such low level changes tends to stir up sediment on the bottom of the pond, making app's that would once build correctly, potentially  fail.


Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on September 04, 2010, 12:22:47 PM
     PlayBASIC V1.64M  Beta #18 - Beta

        This version includes newly built Compiler and Runtimes for BETA TESTING...   I HIGHLY RECOMMEND  trying your project in this edition, not just from the ide / runtime but from a built EXE.


       Download
   
        deleted  


Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on September 14, 2010, 02:38:28 PM

  PlayBASIC V1.64M  Beta #19 - Booter Problems
   
     Back working away on the V1.64M upgrade after noticing a few issues with the beta 18's boot process, which is basically none existent.   Currently i'm just testing beta #19 across the machines here with the slightly tweaked version of the Word Zap game (two birds, 1 stone), and it all seems to be working as expected, so hopefully that's one stumbling block out of the way.    Should be able to get back to the final push to the final of the V1.64M upgrade pretty soon. 

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on September 23, 2010, 02:42:20 AM
   PlayBASIC V1.64M  Beta #21 - Ray Hit Map Pixels (again)

    Back working on the V1.64M upgrade again, this afternoons focus has been on mapping, most notably implementing support for the ray to map functions to support both Video and FX maps.   Was trying for a generic solution originally, but things don't always work the way i'd like, namely it's not really fast enough for the type of abuse such a function is bound to receive.    So after a bit of tinkering and another reshuffle of the algorithm,  I think i've hit upon a solution I can live with in terms of code length and it's performance should be pretty good once implemented.  Currently i'm just testing the theory in PB first.  The main change is that routine now has modes for scanning the various internal map zones, which should be a faster in the real world.


Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on September 24, 2010, 02:30:52 AM
 PlayBASIC V1.64M  Beta #21 - Ray Hit Map Pixels (continued)

   Yesterday I was testing out another ray to map pixels method, today that theory has been implemented into PB.  The change is about twice as fast as the fastest version of older implementation.  Given the circumstances of the demo (It's virtually an array of unique and entirely transparent blocks)  that's about limit of where we can go with this, given it's a brute force test after all.   Normally we've use Ray intersection for this stuff. Which by the way, is why we have worlds :)

    In the demo the map is made up (in code) of 4096 unique 100*100 (32bit) blocks.   In the whole level there's only 1 tile that's known to be fully transparent.  In a real map though there's going to be load of them. The updated scanner is opt'd with this situation in mind.   It's doesn't support animated maps though.  

[pbcode]


screen=newfximage(6400,6400)
rendertoimage screen
cls $ff0000
circlec 400,400,400,true,$ffffff
circlec 1300,400,400,true,$0fffaf


BlockWidth=100
BlockHeight=100

Map=Newmap(50)
createmapgfx  Map,BlockWidth,BlockHeight,4096,$00ff0000,2   ; CREATE 4096 FX BLOCKS

Level=NewLevel(Map,GetSurfaceWidth()/BlockWidth,GetSurfaceHeight()/BlockHeight)
leveltransparent Map,Level,200

   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
             ink $ffff00ff
             text Xpos,ypos,Tile
             ink $ffffffff
            GetMapBlk Map,Tile,Xpos,ypos
            PokeLevelTile Map,Level,xlp,ylp,tile
            #print GetMapBlockTransparent(Map,Tile)
             tile++   
            if Tile=>GetMapBlocks(Map) then exitfor ylp
          next
      endif
   next

;GetMapBlockTransparent

   rendertoscreen

   cam=newcamera()
   cameracls cam,off

   c1=rndrgb()
   c2=rndrgb()

   Do

      shadebox 0,0,getsurfacewidth(),GetsurfaceHeight(),c1,c1,c2,c2

      MouseWorldXpos=MouseX()-1+GetCameraX(Cam)       
      MouseWorldYpos=MouseY()-1+GetCameraY(Cam)      

      capturetoscene   
      clsscene   

      capturedepth 100

      ; draw the map level
      drawmap map,Level,0,0

      ; DRaw the the Mouse pointer within the world space
      capturedepth 10
;      dotc MouseWorldXpos,MouseWorldYpos,RndRGB()


         RayStart=Timer()
         CheckRays(Map,Level,MouseWorldXpos,MouseWorldYpos,300,128)
;         CheckRays(Map,Level,MouseWorldXpos,MouseWorldYpos,300,64)
         RayTime=Timer()-RayStart
      
      ; draw whatever the camera can see
         drawcamera cam

         setcursor 0,0         
         
         ink $ff0000ff
   
         print "Ray Timer:"+STR$(RAYTIME)
      

         speed=2
         if leftkey()    then movecamera cam,-Speed,0
         if rightkey()    then movecamera cam,Speed,0
         if upkey()       then movecamera cam,0,-Speed
         if downkey()    then movecamera cam,0,Speed

      Sync
   loop




Function CheckRays(Map,Level,Xpos,Ypos,RAdius,Rays)
      AngleStep#=360.0/Rays

         For lp=0 to rays-1
               angle#=lp*AngleStep#
               x2#=cosnewvalue(xpos,Angle#,radius)
               y2#=sinnewvalue(ypos,Angle#,radius)
               Collision=RayHitMapPixels(Map,Level,xpos,ypos,x2#,y2#)
                if Collision
                      hitx#=getINtersectx#(0)
                      hity#=getINtersecty#(0)
                      line xpos,ypos,hitx#,hity#
                      circlec hitx#,hity#,5,true,$00ff0000   
               else
                  line xpos,ypos,x2#,y2#
               endif
         next   
      

EndFunction

[/pbcode]



Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on September 27, 2010, 02:06:49 AM
 PlayBASIC V1.64M  Beta #22 - Ray Hit Map Pixels Video Maps

  Finally got this working on maps with graphic blocks in Video memory.   On the surface it's one of those simple little additions that's easily glossed over, then you run into the reality of doing it.    The goal with the updated implementation has been to avoid fetching video memory, which you should know (by now) is slow, so the routine tries to avoid this as much of possible.  But you know at the end of the day it has to do this.  So running lots of ray intersections on  video blocks is going to eat up lots of time, but you should be able to get away doing a little bit of it.  

  Another change that's come as a by product of recent mapping additions, is that map engine now keeps better track of each graphic blocks tranparency status.  Previously you could query if  block was Solid (0) or Transparent (1) (GetMapBlockTransparent), but now another state has been added,  this state lets us know that this graphic block is completely transparent (-1).  This new state allows the ray scanner and map drawing routines some more early rejection options.
   
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on September 28, 2010, 10:43:18 AM
 PlayBASIC V1.64M  Beta #23 - Auto Block Reductions

   Today i've working away on the mapping.  So far I've shrunk much of the map drawing routines down into a much simpler set of routines.  This seems to have given us a bit of a free speed up, although that's most likely from the block transparency additions a few days ago.   Another addition that's been made to the library, is the import routines now attempt to reduce the drawing surface of each block as much as possible.   To demostrate this, i'm using the previous demo code (posted a above), but this time it's drawing  a grid over the level   and drawing blocks that are meant to be transparent using the solid filler just to show the area that's actually being drawn.   If you look closely you'll see the reductions.     

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on September 28, 2010, 11:49:08 PM
 PlayBASIC V1.64M  Beta #24 - Testing Holly

   The screen shot bellow is from Steve's platform game Holly (http://www.underwaredesign.com/forums/index.php?topic=3144.msg23045#msg23045),  I'm using this as real world test of the map block reduction routines, which seem to be working fairly well.    If you look at the shot, the Green Grid is the Maps Debug mode, the overlaid red bounding boxes show the smallest possible rect that this block covers.  Performance wise it's hard to tell really (as i've no bench mark for Holly), but  we've certainly saving a few % off the top of the rendering time.    Every little bit helps !

   

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on September 29, 2010, 07:28:48 AM
 PlayBasic V1.64 Beta #24 Released

  The latest beta is available for download the registered users.  

  [plink] Download PlayBasic V1.64 Beta #24 (http://www.underwaredesign.com/forums/index.php?topic=1150.msg23064#msg23064)[/plink]
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on October 03, 2010, 06:38:22 AM
  PlayBASIC V1.64M  Beta #25 - Rect Hit Map (Collision)

    Now that the Ray & Pixel Methods are implemented, focus has turned to the adding some more methods, starting with RectHitMap function.  This function does exactly what the name suggests, it detects if a rectangle (none rotated) hits on a solid region of the map.  This is not Pixel level impact it's a region impact.  The pixel version will follow.  Had a few drama's getting this work, which turned out to be some misaligned reads from the level..
 
   In the shot  bellow we see the running example (code bellow) which creates a map out of some circles and then runs collision upon them.  The collision not at pixel level  but region level, so the impacts occur when the rectangle overlaps a solid tile or a transparent tiles smallest rect.  


[pbcode]




 BackdropColour=$ff0000

screen=newfximage(6400,6400)
rendertoimage screen
cls  BackdropColour
circlec 400,400,400,true,$ffffff
circlec 1300,400,400,true,$0fffaf

for lp=0 to 150
       ellipsec rnd(2400),rnd(800),rndrange(50,150),rndrange(10,50),true, BackdropColour
next

BlockWidth   =100
BlockHeight=100

Map=Newmap(50)
createmapgfx  Map,BlockWidth,BlockHeight,4096,$00ff0000,2; CREATE 4096 FX BLOCKS

Level=NewLevel(Map,GetSurfaceWidth()/BlockWidth,GetSurfaceHeight()/BlockHeight)
leveltransparent Map,Level,0

   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
             ink $ffff00ff
;             text Xpos,ypos,Tile
             ink $ffffffff
            GetMapBlk Map,Tile,Xpos,ypos
;            text Xpos,ypos,GetMapBlockTransparent(Map,Tile)
;            GetMapBlk Map,Tile,Xpos,ypos
            #print GetMapBlockTransparent(Map,Tile)

            PokeLevelTile Map,Level,xlp,ylp,tile
             tile++   
            if Tile=>GetMapBlocks(Map) then exitfor ylp
          next
      endif
   next

;GetMapBlockTransparent

   rendertoscreen

   cam=newcamera()
   cameracls cam,off

   c1=rndrgb()
   c2=rndrgb()


   Screen=NEwIMage(800,600)
   rendertoimage screen   
      shadebox 0,0,getsurfacewidth(),GetsurfaceHeight(),c1,c1,c2,c2
   rendertoscreen   

   Do

      drawimage screen,0,0,false
   
      MouseWorldXpos=MouseX()-1+GetCameraX(Cam)       
      MouseWorldYpos=MouseY()-1+GetCameraY(Cam)      

      capturetoscene   
      clsscene   

      capturedepth 100

      ; draw the map level
      
      drawmap map,Level,0,0
      ; DRaw the the Mouse pointer within the world space
      capturedepth 10

         RayStart=Timer()
;      CheckRays(Map,Level,MouseWorldXpos,MouseWorldYpos,300,128)
;
;         MouseWorldXpos,MouseWorldYpos,300,128
         x2=MouseWorldXpos+20
         y2=MouseWorldYpos+20

         Collision=RectHitMap(Map,Level,MouseWorldXpos,MouseWorldYpos,x2,y2)

         if Collision
            Colour=$ff0000   
            Print "Rect Hit"
         else
            Colour=$0000ff
            Print "Rect Missed"
         endif
         boxc MouseWorldXpos,MouseWorldYpos,x2,y2,true,colour
         
         RayTime=Timer()-RayStart
      
      ; draw whatever the camera can see
         drawcamera cam

         setcursor 0,0         
         
         ink $ff0000ff
   
         print "Ray Timer:"+STR$(RAYTIME)
      
         speed=2
         if leftkey()    then movecamera cam,-Speed,0
         if rightkey()    then movecamera cam,Speed,0
         if upkey()       then movecamera cam,0,-Speed
         if downkey()    then movecamera cam,0,Speed
         
         
         
         if EnterKey()
            MapDebug Map,1-GetMapDebug(Map)
            flushkeys
         endif

      Sync
   loop

[/pbcode]


PlayBASIC V1.64M  Beta #25 - Rect Hit Map Pixels (Collision)

   The second shot is showing the RectHitMapPixels version of the function.  

[pbcode]


 BackdropColour=$ff0000
 
screen=newfximage(6400,6400)
rendertoimage screen
cls  BackdropColour
circlec 400,400,400,true,$ffffff
circlec 1300,400,400,true,$0fffaf

for lp=0 to 150
       ellipsec rnd(2400),rnd(800),rndrange(50,150),rndrange(10,50),true, BackdropColour
next

BlockWidth   =100
BlockHeight=100

Map=Newmap(50)
createmapgfx  Map,BlockWidth,BlockHeight,4096,$00ff0000,2; CREATE 4096 FX BLOCKS

Level=NewLevel(Map,GetSurfaceWidth()/BlockWidth,GetSurfaceHeight()/BlockHeight)
leveltransparent Map,Level,0

   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
             ink $ffff00ff
;             text Xpos,ypos,Tile
             ink $ffffffff
            GetMapBlk Map,Tile,Xpos,ypos
;            text Xpos,ypos,GetMapBlockTransparent(Map,Tile)
;            GetMapBlk Map,Tile,Xpos,ypos
            #print GetMapBlockTransparent(Map,Tile)

            PokeLevelTile Map,Level,xlp,ylp,tile
             tile++   
            if Tile=>GetMapBlocks(Map) then exitfor ylp
          next
      endif
   next

;GetMapBlockTransparent

   rendertoscreen

   cam=newcamera()
   cameracls cam,off

   c1=rndrgb()
   c2=rndrgb()


   Screen=NEwIMage(800,600)
   rendertoimage screen   
      shadebox 0,0,getsurfacewidth(),GetsurfaceHeight(),c1,c1,c2,c2
   rendertoscreen   

   Do

      drawimage screen,0,0,false
   
      MouseWorldXpos=MouseX()-1+GetCameraX(Cam)       
      MouseWorldYpos=MouseY()-1+GetCameraY(Cam)      

      capturetoscene   
      clsscene   

      capturedepth 100

      ; draw the map level
      
      drawmap map,Level,0,0
      ; DRaw the the Mouse pointer within the world space
      capturedepth 10

         RayStart=Timer()
;      CheckRays(Map,Level,MouseWorldXpos,MouseWorldYpos,300,128)
;
   MouseWorldXpos-=30

;         MouseWorldXpos,MouseWorldYpos,300,128
         x2=MouseWorldXpos+20
         y2=MouseWorldYpos+20

         Collision=RectHitMapPixels(Map,Level,MouseWorldXpos,MouseWorldYpos,x2,y2)


;   capturedepth 200
         if Collision
            Colour=$ff0000   
            Print "Rect Hit"
         else
            Colour=$ffff00
            Print "Rect Missed"
         endif
         boxc MouseWorldXpos,MouseWorldYpos,x2,y2,Collision,colour
         
         RayTime=Timer()-RayStart
      
      ; draw whatever the camera can see
         drawcamera cam

         setcursor 0,0         
         
         ink $ff0000ff
   
         print "Ray Timer:"+STR$(RAYTIME)
      
         speed=2
         if leftkey()    then movecamera cam,-Speed,0
         if rightkey()    then movecamera cam,Speed,0
         if upkey()       then movecamera cam,0,-Speed
         if downkey()    then movecamera cam,0,Speed
         
         if EnterKey()
            MapDebug Map,1-GetMapDebug(Map)
            flushkeys
         endif

      Sync
   loop

[/pbcode]


Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on October 04, 2010, 07:44:32 AM
  PlayBASIC V1.64M  Beta #25 - Circle /Ellipse Hit Map (Testing)

  Just testing some new improved methods for detecting if a circle hits a map.  The first pic shows the map grid, the circle and the zones within the circle and type of collision the zones need.   The second picture is the ellipse version, this time it's showing the zones it passes through.  Inner zones are solid and outer zones are possible transparent zones.
 


Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on October 05, 2010, 07:01:08 AM
  PlayBASIC V1.64M  Beta #25 - Polygon (Quad) Hit Map (Testing)

   Today i've working towards a set of generic polygon to map collision functions. Ideally these functions will detect impacts between a map an a polygon of 3, 4 or user defined sides.  Atm the i'm testing a 4 sided polygon.  The routines (as per the rect and circle and ellipse routines) break down the shape into a grid so the area can be checked against the map.  This allows for early rejection when performing tests against the map and a few other tidbits.. :)

 
   Update: The third shot is showing a 5 sided polygon.  While the routine is running there's still a few teething problems to iron out with method though. 
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on October 07, 2010, 12:10:18 AM

  PlayBASIC V1.64M  Beta #25 - Polygon (Quad) Hit Map (Continued)

     The polygon to map routines are proving to be a bit of a sticking point.  Those will long memories might remember that FX prototypes have some of this functionality built into them.  This thing is, while writing those implementations (which are bit heavy in terms of work load) I'd always wanted to try adding a prescreening ability to reduce the work load where possible.  Which is the main idea behind the current tests.  That being the routine works out what blocks the polygon is going to impact with, then we can do a quick trivial reject/inclusion at this point, rather than needing to jump straight into the pixel to pixel level impacts.

     It's in this speed up thats causing the issues,  the first past has to be fast and accurate.  Which is something of an oxymoron, normally when you optimize for speed,  accuracy is compromised.   In this case when it's not 100% accurate it can return false positives or miss obvious (to the naked eye) intersections.   Which just means that i've been tinkering with a number of different methods of doing the initial classification pass, but without much luck at this point.   The most accurate method so far is also super slow, defeating the purpose of the pass completely. 

     Ideally,  If i can resolve the accuracy issues, such a routine would be handy for scene occlusion purposes.   


Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on October 13, 2010, 11:22:12 AM

  PlayBASIC V1.64M  Beta #25 - Polygon (Quad) Hit Map (Continued)
   
    It's been a busy week (life wise), but even so i've been tinkering with these intersection routines.  Settling on a  hybrid solution that's fairly fast while retaining the accuracy.   The current tech demos are all written in PB (as always) when testing the theory, the next challenge  will be to be build an implementation of them into PB.   So things should progress a little faster now in this regard.  Frankly i'm sick of looking at it.   

   Anyway, here's a look see at the updated method.  In it you can see the quad and the blocks regions masked over the top. The different colours represent the different types of zones.
     
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on October 21, 2010, 01:38:18 PM
  PlayBASIC V1.64M  Beta #25b - Ellipse & Rect/Polygon Hit Grid

   Yep, it's come full circle and we're back to looking at ellipses with some grid masked over the top.    The only difference is, this one's built into PB and no longer a running theory.   Speed wise it's OK, the routine is certainly quick enough to be more than useful, but it's a little slower than I'd like.  But i'd much rather get it working, than tinker with the method anymore.  


   Edit: Testing the grid conversion with polygon mapper, seems to be works fine.
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on October 23, 2010, 01:14:08 AM
  PlayBASIC V1.64M  Beta #26 - Ellipse/Circle to Map

   Been working my way through the actual implementation of the Ellipse/Circle Hit Map function.  The pre-scanning part of the method is in and working well.   So when the interior solid part of the circle/ellipse covers the map, we can get an impacts.    The beauty of this we don't actually need to read the maps pixel data.

  All that's left for this version of the function is to add checks for those regions that circle/ellipse partly covers (those on the boundary).  For this we need another collision method to quickly detect when Ellipse/Circle & Rect regions overlap.

    Bellow i've been tinkering (in PlayBasic) with a few ways to detecting intersections between the two shapes (Since there's no built in method already, or at least I can't find it :) ).  The first demo picture bellow is comparing the screen full of the square tiles to the ellipse.  Those that intersect are highlighted in red.  Giving much the same effect as some of the previous shots in this thread, but achieving it a completely different way.    All that's left to do is port this into the maths library and we should finally be able to tick the CircleHitMap / EllipseHitMap functions off the the To DO List.   Of course, then we need Pixel To Pixel level intersections.  

   The second shot shows the CircleToMap test, you can see it's highlighting the interior tiles of the circle, so if any of this map tiles have pixels in them, then there must and collision.

   Edit:  The third shot is showing the collision test up and running.  In this shot, when the circle edges can now be compard against the maps blocks rects.   So we can get a pretty good indication of what we've hitting.   

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on October 23, 2010, 09:43:05 AM
  PlayBASIC V1.64M  Beta #26 - Ellipse/Circle to Map (cont)

   The CircleHitMap function is up and running.  Before we proceed, I just wanted to really raise the awareness about how intensive these types of collision methods can be.  In the first picture / example bellow we're testing a circle of radius 300 to the map,  not once though but 1000 times.    While really excessive the process eats around 28 to 32 milliseconds at this size.    The size matters since we're translating the shape back to a the map, then comparing them.  The larger the shape the larger the potential work load for the collision engine.  By comparison, if the set the Radius to 30 and run it 1000 times,  it eats about 4 to 6 milliseconds.   So, like everything think carefully about what you're doing when implementing your collisions.

 
[pbcode]



 BackdropColour=$008f00

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

for lp=0 to 150
       ellipsec rnd(2400),rnd(800),rndrange(50,150),rndrange(10,50),true, BackdropColour
next

BlockWidth   =32
BlockHeight=32

Map=Newmap(50)
createmapgfx  Map,BlockWidth,BlockHeight,4096,BackdropColour,2; CREATE 4096 FX BLOCKS

Level=NewLevel(Map,GetSurfaceWidth()/BlockWidth,GetSurfaceHeight()/BlockHeight)
leveltransparent Map,Level,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
             ink $ffffffff
            GetMapBlk Map,Tile,Xpos,ypos
            PokeLevelTile Map,Level,xlp,ylp,tile
             tile++   
            if Tile=>GetMapBlocks(Map) then exitfor ylp
          next
      endif
   next

   rendertoscreen


   c1=rndrgb()
   c2=rndrgb()



   Screen=NEwfxIMage(800,600)

   BackDrop=NEwfxIMage(800,600)
   rendertoimage Backdrop   
      shadebox 0,0,getsurfacewidth(),GetsurfaceHeight(),c1,c1,c2,c2
   rendertoscreen   

   RadiusX=200
   RadiusY=200


   Do
      rendertoimage Screen
   
      drawimage BackDrop,0,0,false
   
      MouseWorldXpos=MouseX()
      MouseWorldYpos=MouseY()
      
      ; draw the map level
      
      drawmap map,Level,0,0


         lockbuffer
         radius=300
         t=timer()
            for lp=0 to 1000
               Collision=CircleHitMap(Map,Level,MouseWorldXpos,MouseWorldYpos,RAdius)
            next
         te=timer()-t
         unlockbuffer

         Print "testing "+Str$(lp)+" times"

         if Collision
            Colour=$ff0000   
            Print "Hit"
         else
            Colour=$0000ff
            Print "Missed"
         endif
         inkmode 1+32
         Circlec MouseWorldXpos,MouseWorldYpos,Radius,true,colour
         inkmode 1

         print te
   
         setcursor 0,0         
         ink $ff0000ff
         
         if EnterKey()
            MapDebug Map,1-GetMapDebug(Map)
            flushkeys
         endif
         
         rendertoscreen
         drawimage screen,0,0,false

      Sync
   loop



[/pbcode]
   


Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on October 24, 2010, 09:13:04 AM
  PlayBASIC V1.64M  Beta #26 - Ellipse/Circle to Map Video

   Finally the Pixel collision version of these functions working very early this morning.   Rather than post another screen shot,  decided to make a little video.

   You can  watch  CircleHitMapPixels video (http://www.youtube.com/watch?v=6Fozk_Su2a0) on our PlayBasic channel  on YouTube


   





 EllipseHitMapPixels Test Source
 
  Here's the test code for the Circle/Ellipse Hit Map demos. (picture attached)

 [pbcode]


 BackdropColour=$ff0000

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

for lp=0 to 150
       ellipsec rnd(2400),rnd(800),rndrange(50,150),rndrange(10,50),true, BackdropColour
next

BlockWidth   =32
BlockHeight=16

Map=Newmap(50)
createmapgfx  Map,BlockWidth,BlockHeight,4096,BackdropColour,2; CREATE 4096 FX BLOCKS

Level=NewLevel(Map,GetSurfaceWidth()/BlockWidth,GetSurfaceHeight()/BlockHeight)
leveltransparent Map,Level,0

   GetMapBlk Map,0,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
             ink $ffff00ff
;             text Xpos,ypos,Tile
             ink $ffffffff
            GetMapBlk Map,Tile,Xpos,ypos
;            text Xpos,ypos,GetMapBlockTransparent(Map,Tile)
;            GetMapBlk Map,Tile,Xpos,ypos
            if GetMapBlockTransparent(Map,Tile)>-1
               PokeLevelTile Map,Level,xlp,ylp,tile
                tile++   
            else
               PokeLevelTile Map,Level,xlp,ylp,0
            endif

            if Tile=>GetMapBlocks(Map) then exitfor ylp
          next
      endif
   next


   Screen=NEwfxIMage(800,600)

   rendertoimage Screen
   
   cam=newcamera()
   cameracls cam,off

   c1=rndrgb()
   c2=rndrgb()




   BackDrop=NEwfxIMage(800,600)
   rendertoimage Backdrop   
      shadebox 0,0,getsurfacewidth(),GetsurfaceHeight(),c1,c1,c2,c2
   rendertoscreen   

   RadiusX=100
   RadiusY=200


   Do
   
      MouseWorldXpos=MouseX()-1+GetCameraX(Cam)       
      MouseWorldYpos=MouseY()-1+GetCameraY(Cam)      

      capturetoscene   
      clsscene   

      capturedepth 200
   
      drawimage BackDrop,GetCameraX(Cam),GetCameraY(Cam),false

      capturedepth 100

      ; draw the map level
      
      drawmap map,Level,0,0
      ; DRaw the the Mouse pointer within the world space
      capturedepth 10

         Collision=EllipseHitMapPixels(Map,Level,MouseWorldXpos,MouseWorldYpos,RAdiusX,RadiusY)


         if Collision
            Colour=$ff0000   
            Message$="Hit"
         else
            Colour=$0000ff
            Message$="Missed"
         endif
         inkmode 1+32
         Ellipsec MouseWorldXpos,MouseWorldYpos,RadiusX,RadiusY,true,colour

         inkmode 1



      ; draw whatever the camera can see
         drawcamera cam

         drawimage screen,0,0,false



         setcursor 0,0         
         ink $ffffffff
         print "Ellipse Hit Map Pixels"
         Print "testing "+Str$(lp)+" times"
         print Message$

   
         if LeftMouseBUtton()
               RAdiusX+=1
               If RadiusX>300 then RadiusX=1            
         endif   
   
         if RightMouseBUtton()
               RAdiusY+=1
               If RadiusY>300 then RadiusY=1            
         endif   


         speed=2
         if leftkey()    then movecamera cam,-Speed,0
         if rightkey()    then movecamera cam,Speed,0
         if upkey()       then movecamera cam,0,-Speed
         if downkey()    then movecamera cam,0,Speed
         
         
         
         if EnterKey()
            MapDebug Map,1-GetMapDebug(Map)
            flushkeys
         endif
         

      Sync
   loop

 [/pbcode]




 PlayBASIC V1.64M  Beta #27 - Quad to Map Collision

  Tonight's little task has been to build the Polygon to map collision routines,  this is relatively simple as the process is much the same as the Circle/Ellipse version except we're feeding it a convex polygon to start with.  It'll actually actually work for the polygons with more than 3 or 4 vertex, but that's something for the future.  

  Anyway, the second shot is showing this QuadHitMap function up and running in Beta 27...   It's a bit quicker than the circle/ellipse version, as calling the routine 1000 times is about 50% faster.   And there's a bit of room to move in terms of further optimizations, but for now i'm just trying to keep the implementation as short as possible.  








Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on October 25, 2010, 02:25:31 PM
  PlayBASIC V1.64M  Beta #27 - Quad Hit Map Pixels Collision

   Another day and another feature collision featured ticked off the To do list.     Yesterday I was getting the vector version of this command running, now we have the pixel version running.  The vector versions of collision commands detect a collision with the mathematical region that shape in question represents.   The pixel versions that this further and attempt a pixel to pixel level impact.   Where and when you'd use them largely depends upon what you're trying to do.  


 Here's the test code bellow


[pbcode]


Dim Vertx#(4)
Dim VertY#(4)


 BackdropColour=$ff0000

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

for lp=0 to 150
       ellipsec rnd(2400),rnd(800),rndrange(50,150),rndrange(10,50),true, BackdropColour
next

BlockWidth   =64
BlockHeight=64

Map=Newmap(50)
createmapgfx  Map,BlockWidth,BlockHeight,4096,BackdropColour,2; CREATE 4096 FX BLOCKS

Level=NewLevel(Map,GetSurfaceWidth()/BlockWidth,GetSurfaceHeight()/BlockHeight)
leveltransparent Map,Level,0

   GetMapBlk Map,0,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
             ink $ffff00ff
;             text Xpos,ypos,Tile
             ink $ffffffff
            GetMapBlk Map,Tile,Xpos,ypos
;            text Xpos,ypos,GetMapBlockTransparent(Map,Tile)
;            GetMapBlk Map,Tile,Xpos,ypos
            if GetMapBlockTransparent(Map,Tile)>-1
               PokeLevelTile Map,Level,xlp,ylp,tile
                tile++   
            else
               PokeLevelTile Map,Level,xlp,ylp,0
            endif

            if Tile=>GetMapBlocks(Map) then exitfor ylp
          next
      endif
   next


   Screen=NEwfxIMage(800,600)

   rendertoimage Screen
   
   cam=newcamera()
   cameracls cam,off

   c1=rndrgb()
   c2=rndrgb()




   BackDrop=NEwfxIMage(800,600)
   rendertoimage Backdrop   
      shadebox 0,0,getsurfacewidth(),GetsurfaceHeight(),c1,c1,c2,c2
   rendertoscreen   

   RadiusX=100
   RadiusY=200


   Do
   
   setcursor 0,0
      MouseWorldXpos=MouseX()-1+GetCameraX(Cam)       
      MouseWorldYpos=MouseY()-1+GetCameraY(Cam)      

      capturetoscene   
      clsscene   

      capturedepth 200
      drawimage BackDrop,GetCameraX(Cam),GetCameraY(Cam),false

      capturedepth 100

      ; draw the map level
      
      drawmap map,Level,0,0
      ; DRaw the the Mouse pointer within the world space
      capturedepth 10

;         t=timer()

         Angle#=wrapangle(Angle#,1)


   capturedepth 1      

   inkmode 1+32

      Count=0
      Height=70
      For ylp=100 to 1000 step 150
         Width=70
         For xlp=00 to 2000 step 150
            Collision=DRawQuad(Map,level,Xlp,ylp,Width,Height,Angle#+width)
            Width+=5
         Count++
      next
         Height+=5
      next         

         te=timer()-t

      Collision=DRawQuad(Map,level,MouseWorldXpos,MouseWorldYpos,RadiusX,RadiusY,Angle#)
      inkmode 1

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


      ; draw whatever the camera can see
         drawcamera cam
      rendertoscreen

         drawimage screen,0,0,false



         setcursor 0,0         
         ink $ffffffff
         print "Quad Hit Map Pixels"
         Print "testing "+Str$(Count)+" times"
         print Message$
         print te
         
   
         if LeftMouseBUtton()
               RAdiusX+=1
               If RadiusX>300 then RadiusX=1            
         endif   
   
         if RightMouseBUtton()
               RAdiusY+=1
               If RadiusY>300 then RadiusY=1            
         endif   


         speed=3
         if leftkey()    then movecamera cam,-Speed,0
         if rightkey()    then movecamera cam,Speed,0
         if upkey()       then movecamera cam,0,-Speed
         if downkey()    then movecamera cam,0,Speed
         
         
         
         if EnterKey()
            MapDebug Map,1-GetMapDebug(Map)
            flushkeys
         endif
         

      Sync
   loop




Psub DRawQuad(ThisMap,ThisLevel,X,Y,Width,Height,Angle#)
;      text 100,100,"Drawing Quad"

      vertx#(0)=(Width/-2.0)
      verty#(0)=(Height/-2.0)

      vertx#(1)=(Width/2.0)
      verty#(1)=(Height/-2.0)

      vertx#(2)=(Width/2.0)
      verty#(2)=(Height/2.0)

      vertx#(3)=(Width/-2.0)
      verty#(3)=(Height/2.0)
      
      ca#=cos(angle#)
      sa#=sin(angle#)

      For lp=0 to 3
            xpos#=   vertx#(lp)
            ypos#=   verty#(lp)
            vertx#(lp)=floor(x+((ca#*xpos#)-(sa#*ypos#)))
            vertY#(lp)=floor(y+((ca#*ypos#)+(sa#*xpos#)))
      next
      Collision=QuadHitMapPixels(ThisMap,ThisLevel,vertx#(0),vertY#(0),vertx#(1),vertY#(1),vertx#(2),vertY#(2),vertx#(3),vertY#(3) )

   if Collision
      col=$f06070    
   else
      Col=$5060f0
   endif      

      QuadC vertx#(0),vertY#(0),vertx#(1),vertY#(1),vertx#(2),vertY#(2),vertx#(3),vertY#(3),Col

EndPsub Collision

[/pbcode]




PlayBASIC V1.64M  Beta #27 - Triangle Hit Map Pixels Collision

   Quickly tacked in the Triangle versions of the function.   Obviously they're really the same routines behind the scenes, we're just piping in 3 verts for a triangle and 4 for a quad.   Performance wise it's perhaps a little faster, but that'd be due to the reduction in area the triangles are covering.    





PlayBASIC V1.64M  Beta #28 - Shape Hit Map Collision

  Working on the ShapeHitMap routine, so far it's just started to work.  There's a few gremlins though when it's scaled for some odd reason, but that'll have to wait till i've had some sleep.






Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on October 26, 2010, 04:10:25 PM

   PlayBASIC V1.64M  Beta #28 - Shape Hit Map Collision

     After a little bit of detective work it seems the odd issues with the ShapeHitMap function were caused from bounding radius of the shape.  So i've ended up replacing the bulk of that part of the library, which was unexpected, but should be for the better across the board.       The shot bellow shows the shape (the donut thing) mapped around a hard region of a block.   So it's seems to be working fairly well for the most, but there's a few annoying little overheads when calling it 1000's of  times, mostly when there's a near miss.   Which In real world situation is pretty unlikely.

   
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on October 28, 2010, 08:40:47 AM
   PlayBASIC V1.64M  Beta #28 - Shape Hit Map Pixels Collision

   This is the Pixel Version of the command, which is currently about 95% up and running, there's a few little oddities left to iron out (namely when the shape is moved to a  negative y position it crashes).    Shapes unlike the Triangle and Quad polygon routines (which are always convex) are a little more of a hand full in these types of situations.  As a shape can not only only represent convex polygons, but they can also be concave and even complex (edges that intersect).   So I can't reply upon the same redundancy assumptions, making this one of the more brute force routines when deal with maps.  

   Anyway, bellow we see the donut shape being compared to the map on pixel and pixel basis.



[pbcode]


   ThisShape=NewConvexShape(50,8)
   TempShape=NewConvexShape(100,6)
   MergeShape TempShape,ThisSHape  

 BackdropColour=$ff0000

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

for lp=0 to 250
       ellipsec rnd(2400),rnd(800),rndrange(50,150),rndrange(10,50),true, BackdropColour
next

BlockWidth   =48
BlockHeight=48

Map=Newmap(50)
createmapgfx  Map,BlockWidth,BlockHeight,4096,BackdropColour,2; CREATE 4096 FX BLOCKS

Level=NewLevel(Map,GetSurfaceWidth()/BlockWidth,GetSurfaceHeight()/BlockHeight)
leveltransparent Map,Level,0

   GetMapBlk Map,0,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
             ink $ffffffff
            GetMapBlk Map,Tile,Xpos,ypos
            if GetMapBlockTransparent(Map,Tile)>-1
               PokeLevelTile Map,Level,xlp,ylp,tile
                tile++   
            else
               PokeLevelTile Map,Level,xlp,ylp,0
            endif

            if Tile=>GetMapBlocks(Map) then exitfor ylp
          next
      endif
   next


   Screen=NEwfxIMage(800,600)

   rendertoimage Screen
   
   cam=newcamera()
   cameracls cam,off

   c1=rndrgb()
   c2=rndrgb()




   BackDrop=NEwfxIMage(800,600)
   rendertoimage Backdrop   
      shadebox 0,0,getsurfacewidth(),GetsurfaceHeight(),c1,c1,c2,c2
   rendertoscreen   

   RadiusX=100
   RadiusY=200

   scale#=1

   Do
   
   setcursor 0,0
      MouseWorldXpos=MouseX()-1+GetCameraX(Cam)       
      MouseWorldYpos=MouseY()-1+GetCameraY(Cam)      
;      rendertoimage Screen

      capturetoscene   
      clsscene   

      capturedepth 200
   
      drawimage BackDrop,GetCameraX(Cam),GetCameraY(Cam),false

      capturedepth 100

      ; draw the map level
      
      drawmap map,Level,0,0
      ; DRaw the the Mouse pointer within the world space
      capturedepth 10


         t=timer()


      if midMousebutton()
         Angle#=wrapangle(Angle#,1)
      
      endif
      
      if LeftMousebUtton()
         scale#+=0.001
         if Scale#>3 then Scale#=0.5
      endif   

         RotateShape ThisShape,Angle#,Scale#
         Collision=ShapeHitMapPixels(Map,Level,ThisShape,MouseWorldXpos,MouseWorldYpos)
      
      if Collision
         col=$f06070    
      else
         Col=$5060f0
      endif      
      inkmode 1+32
         oldcol=getink()
         Ink Col
         drawshape ThisShape,MouseWorldXpos,MouseWorldYpos,2
         ink oldcol
      inkmode 1      
;            next
         te=timer()-t


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


      ; draw whatever the camera can see
         drawcamera cam
      rendertoscreen

         drawimage screen,0,0,false



         setcursor 0,0         
         ink $ffffffff
         print "Shape Hit Map Pixels"
         Print "testing "+Str$(Count)+" times"
         print Message$
         print te
         
   
         if LeftMouseBUtton()
               RAdiusX+=1
               If RadiusX>300 then RadiusX=1            
         endif   
   
         if RightMouseBUtton()
               RAdiusY+=1
               If RadiusY>300 then RadiusY=1            
         endif   


         speed=2
         if leftkey()    then movecamera cam,-Speed,0
         if rightkey()    then movecamera cam,Speed,0
         if upkey()       then movecamera cam,0,-Speed
         if downkey()    then movecamera cam,0,Speed
         
         
         
         if EnterKey()
            MapDebug Map,1-GetMapDebug(Map)
            flushkeys
         endif
         

      Sync
   loop



[/pbcode]

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on October 28, 2010, 09:55:52 AM
  PlayBASIC V1.64M  Beta #28 - Download

  Here's latest build (Beta 28) for your beta testing pleasure.  


   Edit: Newer beta bellow !


Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on October 29, 2010, 12:57:04 AM
  PlayBASIC V1.64M  Beta #29 - Shape Hit Map Pixels Collision(Tweaked)

   This has been really bothering me all night, but after much head scratching finally tracked down the cause the negative Y crashes, which turned out be how the shape was being span converted.   So that issue has been fixed in today's revision, another thing that's bothering me with the pixel to pixel versions is the amount of overhead.

   Some of the overhead was from the debug code drawing the shapes bounding box... erm..  :) -   But a bigger problem was the routine had no obvious way of making an early impact detection.   So i've split the process up.  The separation allows the routines to catch impacts upon solid blocks and exit early.  This change enables us to bypass a lot of the brute force work underneath.  So overlapping big shapes over a map should generally be much faster.

   The logic changes give the ShapeHitMapPixels function a nice little speed boost, bringing it more inline with the Circle/Ellipse & polygon methods.   Bellow in this piccy we're comparing 440 odd shapes to the map scene.   This time the shapes aren't all sitting on top of each other, so the we're getting a more realistic idea of the performance impact.  Previous snippets compare the same shape in the same position to the map.  So they're either all missing completely, partly or they're all near miss at pixel level.  The latter is the worst case, since to resolve them it requires the routine do a brute force compare with the pixels.        

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on October 29, 2010, 04:49:23 PM
 PlayBASIC V1.64M  Beta #29/30 - Sprite Hit Map Pixels Collision(Tweaked)

    It's been another long night digging through some of the long lost (and previously opt'd) collision routines,  but it's been a worthwhile exercise as now we can perform pixel to pixel level impacts between sprites and the map.    Pictured bellow is the first version of the SpriteHitMapPixels function in action.    This function will be used when you want to 'compare' the pixels with the map.  The SpriteHitMap function will use the Sprites current collision mode.  So  a sprites that's set to the rotated rectangle, will compare the a rectangle volume rather than the pixel data.  If it's set to circle, it'll use the circle volume and so on.  If it's set to pixel, then it'll do a Pixel level impact.    
 
    Speed wise the routine is only about  50% slower than the straight vector to pixels methods above when doing a 1000 tests.   Although it really depends upon the situation.  A near miss is the slowest situation.  By that I mean, when the routine has to check lots of pixel data that's very close to the sprite, but not actually overlapping it.   Accuracy wise there's bound to be some variations between the collision span routines and rendering span routines (they use different accuracy).  But that's par for the course I'm afraid.  

   
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on November 01, 2010, 01:49:27 PM
 
PlayBASIC V1.64M  Beta #30 - Download

  Here's latest build (Beta 30) for your continued beta testing pleasure.    This one tweaks the shape hit maps functions and introduces the SpriteHitMapPixels function.  Have fun !


  old file deleted

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on November 04, 2010, 11:17:06 AM
 PlayBASIC V1.64M  Beta #31 - Sprite Hit Map / Supporting all collision modes

    The current task has been getting SpriteHitMap Functions to support various sprite collision modes, which are the Rect, Rotated,Circle,Shape and Pixels.   Here we've looking at the a sprite set to shape mode (with a rough shape outline) in both m,odes.  The first is detecting if the regions overlap, the second is stepping down to pixels.

     The next little challenge will be add support to these routines for video formatted blocks, as currently they only support FX format.

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on November 07, 2010, 05:15:48 AM
  PlayBASIC V1.64M  Beta #32 - Circle/Ellipse/tri and QuadHitMapPixels Support Video Blocks

    Yep, you guessed it, now all of the new collision functions include support for video formatted map blocks.   The only one's remaining are Shape and Sprite modes.  


[pbcode]


Constant VideoBlocks=true


Dim Vertx#(4)
Dim VertY#(4)

BackdropColour=$ff0000

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

for lp=0 to 150
       ellipsec rnd(2400),rnd(800),rndrange(50,150),rndrange(10,50),true, BackdropColour
next

BlockWidth   =64
BlockHeight=64

Map=Newmap(50)
BLockType=2
if VideoBlocks=true then BlockType=1


createmapgfx  Map,BlockWidth,BlockHeight,4096,BackdropColour,1; CREATE 4096 FX BLOCKS
   

Level=NewLevel(Map,GetSurfaceWidth()/BlockWidth,GetSurfaceHeight()/BlockHeight)
leveltransparent Map,Level,0

   GetMapBlk Map,0,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
             ink $ffff00ff
;             text Xpos,ypos,Tile
             ink $ffffffff
            GetMapBlk Map,Tile,Xpos,ypos
;            text Xpos,ypos,GetMapBlockTransparent(Map,Tile)
;            GetMapBlk Map,Tile,Xpos,ypos
            if GetMapBlockTransparent(Map,Tile)>-1
               PokeLevelTile Map,Level,xlp,ylp,tile
                tile++   
            else
               PokeLevelTile Map,Level,xlp,ylp,0
            endif

            if Tile=>GetMapBlocks(Map) then exitfor ylp
          next
      endif
   next



   if VideoBlocks=true
      Screen=NEwIMage(800,600)
   else
      Screen=NEwFXIMage(800,600)
   
   endif


   rendertoimage Screen
   
   cam=newcamera()
   cameracls cam,off

   c1=rndrgb()
   c2=rndrgb()


   BackDrop=NEwfxIMage(800,600)
   rendertoimage Backdrop   
      shadebox 0,0,getsurfacewidth(),GetsurfaceHeight(),c1,c1,c2,c2
   rendertoscreen   

   RadiusX=100
   RadiusY=200


   Do
   
   setcursor 0,0
      MouseWorldXpos=MouseX()-1+GetCameraX(Cam)       
      MouseWorldYpos=MouseY()-1+GetCameraY(Cam)      

      capturetoscene   
      clsscene   

      capturedepth 200
      drawimage BackDrop,GetCameraX(Cam),GetCameraY(Cam),false

      capturedepth 100

      ; draw the map level
      
      drawmap map,Level,0,0
      ; DRaw the the Mouse pointer within the world space
      capturedepth 10

;         t=timer()

         Angle#=wrapangle(Angle#,1)


   capturedepth 1      

         inkmode 1+32
         Collision=EllipseHitMapPixels(Map,level,MouseWorldXpos+300,MouseWorldYpos,RadiusX/2,RadiusY/2)

         if Collision
            Colour=$ff0000   
            Message1$="Hit"
         else
            Colour=$0000ff
            Message1$="Missed"
         endif
      
         EllipseC MouseWorldXpos+300,MouseWorldYpos,RadiusX/2,RadiusY/2,true,colour
         inkmode 1


;   inkmode 1+32

      Count=0
      Height=70
      For ylp=100 to 1000 step 150
         Width=70
         For xlp=00 to 2000 step 150
;            Collision=DRawQuad(Map,level,Xlp,ylp,Width,Height,Angle#+width)
            Width+=5
         Count++
      next
         Height+=5
      next         

         te=timer()-t

         Collision=DRawQuad(Map,level,MouseWorldXpos,MouseWorldYpos,RadiusX,RadiusY,Angle#)
         inkmode 1

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


      ; draw whatever the camera can see
         drawcamera cam
      rendertoscreen

         drawimage screen,0,0,false

         setcursor 0,0         
         ink $ffffffff
         print "Ellipse Hit Map Pixels"+Message1$
         print "Quad Hit Map Pixels"+ Message2$
         
   
         if LeftMouseBUtton()
               RAdiusX+=1
               If RadiusX>300 then RadiusX=1            
         endif   
   
         if RightMouseBUtton()
               RAdiusY+=1
               If RadiusY>300 then RadiusY=1            
         endif   


         speed=3
         if leftkey()    then movecamera cam,-Speed,0
         if rightkey()    then movecamera cam,Speed,0
         if upkey()       then movecamera cam,0,-Speed
         if downkey()    then movecamera cam,0,Speed
         
         
         
         if EnterKey()
            MapDebug Map,1-GetMapDebug(Map)
            flushkeys
         endif
         

      Sync
   loop




Psub DRawQuad(ThisMap,ThisLevel,X,Y,Width,Height,Angle#)
;      text 100,100,"Drawing Quad"

      vertx#(0)=(Width/-2.0)
      verty#(0)=(Height/-2.0)

      vertx#(1)=(Width/2.0)
      verty#(1)=(Height/-2.0)

      vertx#(2)=(Width/2.0)
      verty#(2)=(Height/2.0)

      vertx#(3)=(Width/-2.0)
      verty#(3)=(Height/2.0)
      
      ca#=cos(angle#)
      sa#=sin(angle#)

      For lp=0 to 3
            xpos#=   vertx#(lp)
            ypos#=   verty#(lp)
            vertx#(lp)=floor(x+((ca#*xpos#)-(sa#*ypos#)))
            vertY#(lp)=floor(y+((ca#*ypos#)+(sa#*xpos#)))
      next
      Collision=QuadHitMapPixels(ThisMap,ThisLevel,vertx#(0),vertY#(0),vertx#(1),vertY#(1),vertx#(2),vertY#(2),vertx#(3),vertY#(3) )

   if Collision
      col=$f06070    
   else
      Col=$5060f0
   endif      

      QuadC vertx#(0),vertY#(0),vertx#(1),vertY#(1),vertx#(2),vertY#(2),vertx#(3),vertY#(3),Col

EndPsub Collision



[/pbcode]


Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on November 08, 2010, 12:12:02 AM
  PlayBASIC V1.64M  Beta #33 -  Video Block Support For All MapHitPixel functions + Optimizations

     Added the final couple of video methods in today, they as expected a pretty slow, but they have to be for completeness.  The other thing I've been working on is some optimizations of the built in Level functions.  Namely the removal of the some of the memory management wrapping.  Which is negligible when doing a small number of level reads or writes, but can really compound itself when put under stress reading lots of lots of tiles.  

    To demo this, the code bellow creates a 1000*1000 tile level and then both clones the level using the CloneLevel() and manually compares it with tile by tile.  The results are pretty interesting.  CopyLevel in Beta33 is about 10 times faster than in Beta 30. Moreover the manual compare loop, is about 10% faster.   Which will have a flow on effect.  


[pbcode]

   Map=newmap(32)

   CreateMapGFX map,64,64,5,$000000
   cls 255
   getmapblk  map,0,0,0
   cls $00ff00
   getmapblk  map,1,0,0

   
   Width=1000
   Height=1000
   Level1=newlevel(Map,Width,Height)
   Level2=newlevel(Map,Width*2,Height)

   For Ylp=0 to height-1
      For Xlp=0 to Width-1
         PokeLEvelTile Map,Level1,xlp,ylp,rnd(2)
      next
   next   

   Do

      Cls 0
      
      Frames++
      
      if SpaceKey()=false
         drawmap Map,Level1,0,0
         print "Normal Version"
      else
         drawmap Map,Level2,0,0
         print "Cloned Version"
      endif

      
      t=timer()
      CloneLevel Map,Level1,Map,level2
      tt1#+=timer()-t      
      print "Average Clone Speed:"+str$(tt1#/frames)



      t=timer()
      CompareLevel(Map,Level1,Level2)   
      tt2#+=timer()-t      

      print "Average Manual Compare Speed:"+str$(tt2#/frames)
         
      Sync
   loop



Function CompareLevel(Map,Level1,Level2)

   width      =GetLevelWidth(Map,Level1)
   Height   =GetLevelHeight(Map,Level1)

   For ylp=0 to height   
      For Xlp=0 to Width
         Tile1=PeekLevelTile(Map,Level1,xlp,ylp)
         Tile2=PeekLevelTile(Map,Level2,xlp,ylp)
         if Tile1<>Tile2
               err=1   
               #print "different"
         endif
      next
   next

   if Err
   print "Not the same"
   endif
EndFunction



[/pbcode]



 PlayBASIC V1.64M  Beta #33 -  Download

  old file removed




Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on November 10, 2010, 10:21:01 PM

   PlayBASIC V1.64M  Beta #34 - RectOccludeMap - Manual Occlusion

     Occlusion support is one of things I've been wanted to implement for some time, but there's always the little stumbling block of just how.   For those not familiar, occlusion is a series of conceptual techniques (often customized to the problem) that are used to remove redundant drawing operations from the screen refresh.   The idea being to preemptively prohibit the graphics engine from drawing images that's won't actually be visible to the player, due to being behind something else, so why draw them. 

     A common situation occurs when drawing a multiple map layers over each other.   If we imagine a scene with 2 or more layers, then normally we'd draw them all over each other regardless of what was in screen.  So with 3 layers, we're potentially draw every pixel 3 times.   With modern hardware this is not really that big of a deal (assuming a medium screen resolution), but if you want your games to run on more than just modern windows boxes, then it's worth seeing if we can cull out any of the redunant rendering.  This will help speed up the layer rendering, which could potentially boost you games performance not only on the older machines but newer ones too.  Which means you'll be able to squeeze more action into the game then without it.

     So to help programmers start tackling such problems with maps, i've been implementing a RectOccludeMap function.  This function works out what blocks it's covering within the level, then clears them.  So when the level is rendered,  at section will be blocked out.  To demostrate this , i've  made a little demo with a backdrop picture and single scrolling in the foreground.  The Mouse is moved over the frame and the region it covers is culled from the backdrop. 

     

   

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on November 11, 2010, 07:48:48 AM
   PlayBASIC V1.64M  Beta #34 - 3 Map Layers With Occlusion

    The following pic's and code are an extension of the previous two layer demo.   Except this time, we've added a third layer and some occlusion zones to help masking out the middle background layer.    To build the layers, I've simply drawing a large picture then cut them up into tiles in code.  The middle layer is some random tube things and front layer is of some bricks with a sine wave cut out of it. Neither are optimization into the most minimal block set, but will do for the sake of an example.  

    Without occlusion the demo runs nicely around the 250-270 fps make.   It varies as the on screen pixel count varies frame to frame.   With occlusion the rate sit around the  310-330 fps.   Which in this demo, is about the speed of rendering the two back layers without occlusion.   So we're virtually getting the third layer for free.      


 Requires PlayBasic V1.64  Beta 34!

 [pbcode]

      file$="_INSERT_NAME_OF_BACKDROP_PICTURE_HERE"

      print "Loading Backdrop"
      Sync      
      Backdrop2=LoadNewfxImage(File$)
      scaleimage Backdrop2,GEtImageWidth(Backdrop2),600,1+2      
      Backdrop=NewImage(GEtImageWidth(Backdrop2),600)
      CopyRect Backdrop2,0,0,GEtImageWidth(Backdrop2),600,Backdrop,0,0
      deleteimage backdrop2      

      Constant Projection=400

      SceneWidth   =GetSCreenWidth()*2
      SceneHeight   =GetScreenHeight()*2
   
      Screen=NewFXIMage(SceneWidth,SceneHeight)

      print "Building Tube"
      Sync      

      rendertoimage Screen
      For Z= 3000 to 200 step -50
         width=rndrange(150,250)
         width2=width/2
         x=rndrange(width2,SceneWidth-width2)   
         y=100+rnd(SceneHeight/2)
         ThisRGB=RndRGB()
         DrawTube(x,y,500+z,width,900,ThisRGB)
      next

      rendertoscreen
      print "Building TubeMap"
      Sync      

      TubeMap=MakeMapFromIMage(Screen,24,24)



      rendertoscreen
      print "Building WaveMap"
      Sync      


      File$="D:\Source_Codes\GFX\Textures\Brick.bmp"
      BrickImage=LoadNewImage(File$)
      ScaleImage BrickIMage,32,32,1+2


      RendertoIMage Screen
      Cls 0
      TileImage BrickImage,0,0,true

      ;
      Angle#=0
      AngleStep#=720.0/GetImageWidth(Screen)
      For xlp=0 to GetImageWidth(Screen)
            y=420+sin(Angle#)*100
            linec xlp,y,xlp,0,0
            Angle#+=AngleStep#
      next


      Type TRects
         x1,y1,x2,y2   
      EndType

      Dim GroundZones as tRects list

      AddRect(0,520,GetImageWidth(Screen) ,800)

      AddRect(500,350,700 ,520)
      AddRect(430,400,770 ,580)

      offset=800
      AddRect(offset+500,350,offset+700 ,520)
      AddRect(offset+430,400,offset+770 ,580)



      BrickWallMap=MakeMapFromIMage(Screen,32,32)


      rendertoscreen
      Cam=NewCamera()
      cameracls cam,off


      StartTime=Timer()

      Do
         

         CurrentTime=Timer()
         TimePast=CurrentTime-StartTime

         CaptureToScene
         ClsScene

         iw=GetIMageWidth(Backdrop)
         ScrollSpeed# = Float(iw)/80000
         Xpos=TimePast*ScrollSpeed#

         capturedepth 100
         DrawImage Backdrop,-xpos,0,false
         DrawImage Backdrop,(-xpos)+iw,0,false
         
         ; Scroll speed in pixels per tick
         ScrollSpeed# = Float(SceneWidth)/20000
         Xpos=TimePast*ScrollSpeed#
         LevelWidth=GetLevelabsWidth(Tubemap,1)-GetMapBlockWidth(TubeMap)
         Layer2_Xpos=MOd(Xpos,LevelWidth/2)

         MouseWorldXpos=MouseX()+GetCameraX(Cam)
         MouseWorldYpos=MouseY()+GetCameraY(Cam)

         CloneLevel TubeMap,1,TubeMap,2

         capturedepth 50
      
         DrawMap TubeMap,2,-Layer2_Xpos,0



         ; Scroll speed in pixels per tick
         ScrollSpeed# = Float(SceneWidth)/10000
         Xpos=TimePast*ScrollSpeed#
         LevelWidth=GetLevelabsWidth(BrickWallMap,2)-GetMapBlockWidth(BrickWallMap)
         Layer3_Xpos=MOd(Xpos,LevelWidth/2)

         capturedepth 10

         if spacekey()=false
               DrawMap BrickWallMap,2,-Layer3_Xpos,0
         endif

         capturedepth 1

         for each GroundZones()
               
            x1=GroundZones.x1   -Layer3_Xpos
            x2=GroundZones.x2   -Layer3_Xpos
            y1=GroundZones.y1
            y2=GroundZones.y2
            boxc x1,y1,x2,y2,false,$00ff0000         

            MapSpaceX1=x1+Layer2_Xpos      
            MapSpaceY1=y1      
            MapSpaceX2=x2+Layer2_Xpos      
            MapSpaceY2=y2      
   
            Collision=RectOccludeMap(TubeMap,2,MapSpaceX1,MapSpaceY1,MapSpaceX2,MapSpaceY2)
            
         next
         
         drawcamera cam
         
         if EnterKey()
            MapDebug TubeMap,1-GetMapDebug(TubeMap)
            flushkeys
         endif
   
         Sync
      loop


Function DrawTube(X,Y,z,Width,Height,ThisRgb)

      ThisRgb2=Rgbfade(ThisRgb,50)
      ThisRgb2=RgbAlphaAdd(ThisRgb,$445566)
      AngleStep=20
      For Angle#=270 to 360+270-1 step AngleStep

         if Toggle=0
            R=rgbR(ThisRgb)
            G=rgbG(ThisRgb)
            B=rgbB(ThisRgb)

         else
            R=rgbR(ThisRgb2)
            G=rgbG(ThisRgb2)
            B=rgbB(ThisRgb2)
         
         
         endif   
         Toggle=1-Toggle

         Angle2#=wrapangle(Angle#+angleStep)

         Xpos1=Sin(Angle#)*Width
         Ypos1=y/2
         Zpos1=Z+(Cos(Angle#)*Width)         

         Xpos2=sin(Angle2#)*Width
         Ypos2=y/2
         Zpos2=Z+(Cos(Angle2#)*Width)         
      
      
            X1=x+(Xpos1*Projection/Zpos1)
            X2=x+(Xpos2*Projection/Zpos2)

            Yt1=y+(Ypos1*Projection/Zpos1)
            Yt2=y+(Ypos2*Projection/Zpos2)

               
            r1=(R*Projection)/Zpos1
            g1=(G*Projection)/Zpos1
            b1=(B*Projection)/Zpos1
                           
            r2=(R*Projection)/Zpos2
            g2=(G*Projection)/Zpos2
            b2=(B*Projection)/Zpos2

            Rgb1=Rgb(r1,g1,b1)
            Rgb2=Rgb(r2,g2,b2)
         
            y2=y1+Height

            gouraudtri  x1,yt1,rgb1,x2,yt2,rgb2,x2,y2,rgb2
            gouraudtri  x1,yt1,rgb1,x2,y2,rgb2,x1,y2,rgb1

      next

EndFunction




Function MakeMapFromIMage(ThisIMage,BlockWidth,BlockHeight)
   OldSurface=GetSurface()
   Map=NewMap(16)

   Width      =GetIMageWidth(ThisImage)
   Height   =GetIMageHeight(ThisImage)

   CreateMapGFX  Map,BlockWidth,BlockHeight,2048,BackdropColour,2; CREATE 4096 FX BLOCKS

   Level=1+GetFreeMapLevel(Map)
  CreateLevel Map,Level,Width/BlockWidth,Height/BlockHeight
  leveltransparent Map,Level,0
   rendertoimage ThisImage
   

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

   cloneLevel Map,Level,Map,level+1
   ResizeLevel Map,Level,(LevelWidth)*2,Levelheight
   PasteLevel Map,Level+1,Map,Level,LevelWidth,0,false
   
   #print GetLevelWidth(map,level)
   #print GetLevelHeight(map,level)
   #print Tile

   rendertoimage OldSurface

EndFunction Map






Function AddRect(x1,y1,x2,y2)
      SwapIfhigher x1,x2
      SwapIfhigher y1,y2
      
      GroundZones=new tRects

      GroundZones.x1=x1            
      GroundZones.y1=y1            

      GroundZones.x2=x2            
      GroundZones.y2=y2            

EndFunction      



 [/pbcode]
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on November 12, 2010, 11:01:40 PM
   PlayBASIC V1.64M  Beta #34 - Download

    Posted beta 34, this one has the occlusion commands in it, but only the RectOccludeMap is hooked up.  


  [plink]Get PlayBAsic V1.64 Beta 34 (http://www.underwaredesign.com/forums/index.php?topic=1150.msg23390#msg23390)[/plink]
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on November 15, 2010, 10:58:00 AM
   PlayBASIC V1.64M  Beta #35 - Quad (Polygon) Occlude Map

   Tonight I'm putting the final touches on the occlusion commands, with the addition of the Circle / Ellipse & QuadOccludeMap functions.   They work via the same principal as the Rect version, you give it a shape and it cuts that region out of map level.   Supporting different zones should make it easier for those creative programmers to tweak their games performance just that little bit more.

 

  Download
   
   deleted
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on November 16, 2010, 09:36:53 PM

PlayBASIC V1.64M  Beta #36 -Optimization Stage

     Been sifting through the Shape Library this afternoon trying to improve the speed of the some core functions like PointHitShape, but without altering it's functionality.  So far the results have been fairly pleasing seeing around a 40% gain in performance over a 10000 calls.  This caries through to other routines like the LineHitShape and Shape intersections due to their usage of PointHitShape in certain circumstances.  Giving a nice little boost to demos that usage a lots of shape collisions.
 
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: LBFN on November 16, 2010, 09:50:41 PM
I see that v1.64M has a lot of new features.  I also saw in another thread that you are looking for beta testers for it.  I am interested in providing some feedback via beta testing, but I am afraid that I will have issues like before.  Is there a way to put the 1.64M beta on my computer completely separate from the existing 1.64l ?
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on November 17, 2010, 10:03:25 AM
QuoteI also saw in another thread that you are looking for beta testers for it.

  erm,  Beta testing of V1.64M started 6 months ago and is an ongoing process.


QuoteI am interested in providing some feedback via beta testing, but I am afraid that I will have issues like before.  Is there a way to put the 1.64M beta on my computer completely separate from the existing 1.64l ?

 Either install it to different folder, or copy the previously installed version to some other location.    To apply the beta, unzip the files and copy them over it.  
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: LBFN on November 17, 2010, 10:21:37 AM
I was referring to this comment:
QuoteSo it's looking like we'll get the V1.64M towards the end of the month.     Meaning that we'll need all hands on deck in terms of testing form now on.  Otherwise,  the release version will be an untested  beta...

Thanks for the info.  

EDIT:  That was easy,
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on November 17, 2010, 11:36:30 PM
  PlayBASIC V1.64M  Beta #36 -Optimization Continues

     I've posted today's edition of the beta 36, which includes a number of bug fixes and some neat optimizations.



 

Download

   old version removed

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: LBFN on November 18, 2010, 11:24:05 AM
EDIT:  It is obvious that feedback from me is not wanted.  Okay, I'm a little slow, but I get it.  I really did want to help, but that's fine.
Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on November 21, 2010, 09:20:03 AM
  PlayBASIC V1.64M  Beta #37 -Optimization Continues

     Posted yesterdays build of beta 37, the tweaks are mainly focus on optimizations and bug fixes around shapes.  

 

Download

     old download removed.

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on November 21, 2010, 09:30:04 AM
Quote from: LBFN on November 18, 2010, 11:24:05 AM
EDIT:  It is obvious that feedback from me is not wanted.  Okay, I'm a little slow, but I get it.  I really did want to help, but that's fine.

  What the hell are you talking about ???????????

Title: Re: PlayBasic V1.64M (Work In Progress) Gallery
Post by: kevin on November 24, 2010, 09:17:28 AM
  PlayBASIC V1.64M  Beta #38 -Enters Final Testing Phase

     Beta 38 moves us more into the very final stages of beta testing this update.  In fact, the only changes in this version (from revision 37) are all bugs/tweaks related.