UnderwareDESIGN

General => Competitions => CleverCoders => Topic started by: kevin on March 23, 2012, 02:41:35 AM

Title: Challenge #25 - High Performance 8 Direction Scroller (8 by 8 tile size)
Post by: kevin on March 23, 2012, 02:41:35 AM

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


Challenge #25 - High Performance 8 Direction Scroller (8 by 8 tile size)


   This is a challenge for the more experienced PlayBASIC programmers.  Those that are similar with PlayBASIC know that creating an 8 direction scrolling screen,  as seen in virtually any 2D platform game,  is trivial.    That's not the challenge here.  

  This is a challenge of performance (thinking outside of the box really),  what you have to do. is create a world that's 1024*1024  tiles/blocks wide and high.  Each tile is to be 8 by 8 pixels in size with at least 2 unique tiles.  Giving us a world size in pixels of 8192x*8192y.   The player should be able to scroll in any of the 8 directions, so  Left -> Right -> Up -> Down and their diagonal combination's

   Extra Brownie points will award to submissions over 500fps.  on my test system.



Submission

 * Submissions can be written in any version of PlayBASIC (http://www.playbasic.com)
 
 * Submission can only be accepted in Source Code form only.

 * Authors can use external Media (images/music) provided you created the media/and or have permission to distribute the includes media or the Media is in the public domain.

* Zip up your Submissions and please try to keep it smaller than 500K !

 * Authors automatically give consent for their submission(s) to distributed and used for promotional purposes via UnderwareDesign.com, PlayBasic.com code tank.

* Authors can submit as many times as they like.

 * To make a submission, zip up your projects source code + media and either post it in this thread, or create your own thread in either the Source Codes or Show Case forums and post a link bellow.



Dead Line

    Anytime before the next ice age



Prizes

    * The best submissions will be periodically highlighted through the PlayBasic IDE news service/News Letters/ FaceBook (http://www.facebook.com/pages/PlayBasic/127905400584274) or on Twitter (http://www.twitter.com/PlayBasic)




Return to Challenge Index (http://www.underwaredesign.com/forums/index.php?topic=3225.0)

Title: Re: Challenge #25 - High Performance 8 Direction Scroller (8 by 8 tile size)
Post by: kevin on March 26, 2012, 12:41:25 AM
  Struggling, here's some motivation :) .... The attached piccy shows a demo that converts the Animal picture into a block map 8 times it's size. So each pixel becomes an 8*8 block, just thought it'd make an interesting scene, rather than some random colours.  The user can scroll around the world using the arrows...  The routine runs between 500->700fps (in a window), so around a 2 millisecond refresh.

Title: Re: Challenge #25 - High Performance 8 Direction Scroller (8 by 8 tile size)
Post by: monkeybot on March 26, 2012, 05:08:13 PM
i cant get much over 300 fps.
Title: Re: Challenge #25 - High Performance 8 Direction Scroller (8 by 8 tile size)
Post by: kevin on March 27, 2012, 12:36:03 AM
 Runs around 500fps here, so you can have a nice shiny brownie point

Now obviously, you're on the right track..  The main tip I can give would be to 'manage' the size of the cache image(s).   So find a size that's not too small, or too large.. and you can win even out performance.    

It's interesting you're using an emulated 2D array.  While it doesn't really matter in this particular example,  the approach is slower than a 2D array.  But you can even it out,  by calculating the row and using and Xlp as the inner offset.  Which makes it about the same as a 2D array write performance,  In PB1.64 at least.   Suspect it'd work better if you had to lots of reads from the array.  

[pbcode]
  Width      =256
  Height   =256

   Dim Map1D(Width*Height)
   Dim Map2D(Width,Height)
   

   do
      cls
      
      frames++

      ; Emulated 2D array
      t=timer()      
         For ylp=0 to Height-1
            for xlp=0 to Width-1  
                       Map1D(xlp+(width*ylp))=Colour
             next
         next        
      tt1#+=timer()-t
      print tt1#/frames
            
      ; Emulated 2D array, writing to rows with loop offset
      t=timer()      
         RowOffset=0
         For ylp=0 to Height-1
            for xlp=0 to Width-1  
                       Map1d(RowOffset+xlp)=Colour
             next
             RowOffset+=Width
         next        
      tt2#+=timer()-t
      print tt2#/frames


      ; normal 2d array   
      t=timer()      
         For ylp=0 to Height-1
            for xlp=0 to Width-1  
                     Map2d(xlp,ylp)=Colour
             next
         next        
      tt3#+=timer()-t
      print tt3#/frames
      
      Sync
   loop

[/pbcode]

   

 It's slightly quicker if you have to read/write from the same array cell

[pbcode]

  ; This version adds the colour to each array cell.  So it's reading + writing to the cell

  Width      =256
  Height   =256

   Dim Map1D(Width*Height)
   Dim Map2D(Width,Height)

   Colour =1

   do
      cls
      
      frames++

      ; Emulated 2D array
      t=timer()      
         For ylp=0 to Height-1
            for xlp=0 to Width-1  
                 Address=xlp+(width*ylp)
                 Map1D(Address)+=Colour
             next
         next        
      tt1#+=timer()-t
      print tt1#/frames
            
      ; Emulated 2D array, writing to rows with loop offset
      t=timer()      
         RowOffset=0
         For ylp=0 to Height-1
            for xlp=0 to Width-1  
                 Map1d(RowOffset+xlp)+=Colour
             next
             RowOffset+=Width
         next        
      tt2#+=timer()-t
      print tt2#/frames


      ; normal 2d array   
      t=timer()      
         For ylp=0 to Height-1
            for xlp=0 to Width-1  
                 Map2d(xlp,ylp)+=Colour
             next
         next        
      tt3#+=timer()-t
      print tt3#/frames
      
      Sync
   loop


[/pbcode]



Title: Re: Challenge #25 - High Performance 8 Direction Scroller (8 by 8 tile size)
Post by: monkeybot on March 27, 2012, 02:30:20 AM
woot!! a brownie point,i will clear some space in my trophy cabinet.
the reason i kept the read and write apart was just for flexibility i was messing around with the array data in other read routines.
Title: Re: Challenge #25 - High Performance 8 Direction Scroller (8 by 8 tile size)
Post by: monkeybot on March 27, 2012, 04:35:01 PM
Kevin,
when i run my  above program with fastpoint it crashes,please could you tell me where i have gone wrong.

Cheers.
Title: Re: Challenge #25 - High Performance 8 Direction Scroller (8 by 8 tile size)
Post by: kevin on March 27, 2012, 11:07:31 PM
[pbcode]
  RendertoIMage MyIMage
  Lockbuffer
   For ylp=0 to Height-1
     For xlp=0 to Width-1
        ThisPixel = Point(xlp,ylp)
     next
   next
  unLockbuffer
[/pbcode]

  If you swapped point for fastpoint in a loop like this, then that won't work.   Why ? - FastPoint doesn't have any nanny code in it.  Where regular graphics commands like Point will fill in the internal current surface structure every time they're called, FastPoint doesn't, it just uses whatever the pointer was last set to.   The internal structure is stuff like the address & pitch and of the image data in memory, so it's happily die when it's not pointing at something that's not an image.  

  So before using any "FastPoint"  or "FastDot"  we need to make sure the address/pitch are seeded,  one way is to read a dummy point from the surface before entering the loop.  Like so

[pbcode]
  RendertoIMage MyIMage
  Lockbuffer
   ThisPixel=Point(0,0)
   For ylp=0 to Height-1
     For xlp=0 to Width-1
        ThisPixel = Point(xlp,ylp)
     next
   next
  unLockbuffer
[/pbcode]

Title: Re: Challenge #25 - High Performance 8 Direction Scroller (8 by 8 tile size)
Post by: monkeybot on March 28, 2012, 12:51:09 PM
ahhhhh i see,thanks.

from the Manual

QuoteNote: Before you can use FastPoint correctly. After you lock the draw surface, it's hihgly recommended you read a pixel from this surface using Point(). This will ensure the address of the surface is seeded for FastPoint

i should look harder
Title: Re: Challenge #25 - High Performance 8 Direction Scroller (8 by 8 tile size)
Post by: kevin on March 29, 2012, 11:03:11 AM

erm, yeah..  :)