UnderwareDESIGN

PlayBASIC => Show Case => Topic started by: kevin on January 27, 2013, 10:50:31 PM

Title: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on January 27, 2013, 10:50:31 PM

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


PlayBASIC V1.64O  (Work In Progress) Gallery (January 27, 2013)


    This thread  documents the changes made for the PlayBASIC 1.64 revision O retail upgrade.  

  This upgrade was released (9th,Aug,2013)  (http://www.underwaredesign.com/forums/index.php?topic=1774.msg27548#msg27548)



Upgrade History


    For newer upgrade work in progress see,

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


    For older upgrade work in progress see,

    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)

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

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

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





Upgrade Work in Progress (Blog)




PlayBASIC V1.64O Beta1 - Dynamic Function Calling

     While under the hood, figured I'd tweak the searching up a little more in the CallFunction operation.  If you call a function by name, then it has to search through the function names looking for a match.  The search it self is nothing fancy, it's just a linear search, so figured it'd be a handy place for a hash level pre-screen.  
With the hash,  V1.64O it's about 40% quicker than V1.64N3 using the original bench mark code.




[pbcode]

Print "Dynamic Psub Calling With Parameter"

   Dim FunctionNames$(3)
   Dim FunctionIndexes(3)

   FunctionNames$(0)="Test0"
   FunctionNames$(1)="Test1"
   FunctionNames$(2)="Test2"
   FunctionNames$(3)="Test3"

   FunctionIndexes(0)=FunctionIndex("Test0")
   FunctionIndexes(1)=FunctionIndex("Test1")
   FunctionIndexes(2)=FunctionIndex("Test2")
   FunctionIndexes(3)=FunctionIndex("Test3")
   
   
   Global Value0
   Global Value1
   Global Value2
   Global Value3

   MaxTests=10000

   Do
      Cls 0
      
         frames++

         t=timer()
            for lp=0 to MaxTests-1
               CallFunction FunctionNames$(lp &3),lp
            next
         tt1#+=(timer()-t)
         print tt1#/frames
         print "tests:"+STR$(lp)
        
         t=timer()
            for lp=0 to MaxTests-1
               CallFunction FunctionIndexes(lp &3),lp
            next
         tt2#+=(timer()-t)
         print tt2#/frames
         print "tests:"+STR$(lp)

         print fps()
         print Value0   
         print Value1   
         print Value2
         print Value3   


      Sync
   loop
   



Psub Test0(a)
      Value0++
EndPsub

Psub Test1(a)
      Value1++
EndPsub

Psub Test2(a)
      Value2++
EndPsub

Psub Test3(a)
      Value3++
EndPsub

[/pbcode]


Update:

     Updated the search routine again, stripping another 5->6 milliseconds from the earlier update.    I'd still strongly encourage user to pre-compute the function index prior, rather than dynamically searching for the function name (as a string) every single time.  But it's viable either way.  



Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on January 28, 2013, 10:50:12 PM
PlayBASIC V1.64O Beta1 - Download

    Here's today's build of the V1.64O.   Not too sure what else will make it into this upgrade,  so it might be while before there's a final.  

    removed, newer beta bellow
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on February 03, 2013, 10:51:46 PM
 PlayBASIC V1.64O Beta2 - Small Tweaks

     Add a couple of tiny  tidbits into today's build, the first is a constant to return the current Optimizer state.  (PBOptimizeState),  which allows a include to set the optimizer state it wants/requires without changing the state for the rest of the program.  To do that, you just preserve the state in constant on entry to the code block then restore it at the end.



[pbcode]

   ; remember the current optimizer state   
   COnstant PreServeOptimizeMode = PbOptimizeState
   

   ; Enable Type Caching and general optimizations   
   OptExpressions 3


   ; print Optimizer stat within this block of code      
   print PbOptimizeState

     


   ; restore it at the end of this block of code
   OptExpressions PreServeOptimizeMode


   ; print the optimizer state here
   print PbOptimizeState


   Sync
   waitkey

[/pbcode]  



 64bit Start Interval / End Interval (High Resolution timing)

     Dropped a couple of functions in to query the number of high res ticks between the pair of calls.   The first call stamps the start time, and the End call gets the number of the ticks that has past since the start call.  Internally the timer resolution is 64bit, so the routine returns the interval in 32bit.   On my system the high res timer is about 1000 ticks the resolution of the milliseconds.    It'll actually be different for different CPU's...  But ya get that..

     The Functions use an internal array for storing up to 128 (at this time) unique time points.  Will most likely reduce that to 32 or something.   The high resolution time is just like the millisecond timer,  it's counting up regardless of what app is currently being executed.

[pbcode]

   Max=25000

Do   
   cls
   
   frames++


   ; Set the starting time, so we can time the number of hi
   ; resolution ticks between the pair of calls
   StartInterval(0)   

   ; get the current millisecond when the loop starts
   timeStart=timer()

   ; do a loop for something to time
   For lp =0 to Max
         a=b
   next

   ; get the number of low res / milliseconds that haver past
   Time1=Timer()-TimeStart

   ; get the high resolution of ticks that have past
   time2=EndInterval(0)   

   tt1#+=Time1
   tt2#+=Time2

   print "      Average Ticks:"+str$(tt1#/frames)
   print "Average Hires Ticks:"+str$(tt2#/frames)
      
   sync
loop   



[/pbcode]

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: monkeybot on February 05, 2013, 04:35:22 PM
ooh! i like the sound of that,good for a code profiler maybe?
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on February 07, 2013, 06:21:51 AM
Quoteooh! i like the sound of that,good for a code profiler maybe?

  go for it.


PlayBASIC V1.64O Beta3 - String Fixes

  Dunno how long this one been hanging around, but looking at the source i'd say forever.   Anyway today's little issue was found in the CutRight$() function, when the cut point is less than the first character. Previously it'd return the entire string, now it returns a null string like it should.    I suspect the same fault occurs with cut left also.  Assuming they're cut and paste of each other..  


[pbcode]

   s$="playBASIC"
   
   print "CutRight$"
   for lp =0 to len(s$)+10
         print str$(lp)+CutRight$(s$,lp)
   next
   print ""
   print ""
   print ""

   print "CutLEft$"
   
   for lp =0 to len(s$)+10
         print str$(lp)+CutLeft$(s$,lp)
   next
   
   print ""
   print ""
   print ""

   Sync
   waitkey
   
[/pbcode]


  Edit:  Yes, both functions had similar issues, both run correct now.


Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: monkeybot on February 07, 2013, 03:37:50 PM
are you going to put beta 2 up?
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on February 07, 2013, 09:25:39 PM
Quoteare you going to put beta 2 up?

   It no longer exists.


PlayBASIC V1.64O Beta3 - Download

    Here's today's build of V1.64O.

    removed, newer beta bellow

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: monkeybot on February 08, 2013, 01:05:38 PM
thanks.
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on March 01, 2013, 11:58:30 AM
PlayBASIC V1.64O Beta4

   Just testing an alternative version of the RGB function, since the standard version  expects the 0-255 values for the R components, however sometimes it's easy to use floating point representations in some algorithms.   So in those cases you'd need to mult each component scaler by the 255..  Like so   Rgb(255*R_Level#,255*G_Level#, 255*B_Level#) .   The problem with this is two fold, first you've got the VM running 3 extra floating point mults plus there's no bounds clipping.    

   Performance wise the test function is about 40% faster, which should be handy little gain given it'd generally only be used in brute force loops.   Currently it's called RGB2,  Dunno what i'll actually be called  though..  

[pbcode]

   max=10000

Do
   cls

   frames++

   t=StartInterval(1)
      For lp=0 to max   
         col1= RGB(red# * 255.0, green# * 255.0, blue# * 255.0)
      next
   tt1#+=EndInterval(1)
   print tt1#/frames


   t=StartInterval(1)
      For lp=0 to max   
         col1= RGB2(red# , green# , blue# )
      next
   tt2#+=EndInterval(1)

   print tt2#/frames

   print Fps()

   Sync
loop

[/pbcode]

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: RayRayTea2 on March 02, 2013, 12:28:57 AM
It seems the collision against the tiles with RectHitMap leaks on top and bottom of every tile.

To see the effect load the attached file and try to run it. Move the mouse so the rectangular shape gets close to the tiles. If there's a tile above or to the right of the Rectangle, it will report a collision one tile before it actually happens.

Uncomment line 9 in the "Workers.pba" and comment out line 10 and it'll work correctly... The difference between the two files "tileset.png" and "tileset tweak.png" is that the "tweak" one has top and left row and column of pixels deleted.


The collision still gets triggered with a one pixel difference depending on where you approach the tile from, this can also be seen with shapes and ShapeHitMap. In Workers.pba uncomment line 9 and comment out line 10 , in "Main.pba" uncomment lines 17-20 and comment out lines 23-27 (also uncomment line 22 in SetUp.pba otherwise it'll crash! - this was already reported elsewhere so let's ignore it for now), and you'll see that a collision with a (rectangular non rotated) shape is checked slightly differently depending on whether it's checked against top and left side of a shape or bottom and right sides.

Top and Left side do not report a collision until the shape actually enters into a map tile, while Top and Right sides report a collision as soon as they are one pixel next to a map tile.

Edit: clarification.

Edit2: Weird, in this image (http://www.flickr.com/photos/93171013@N08/8521661210/in/photostream/) the rectangle is not even touching the green area yet it triggers the collision, while this one's (http://www.flickr.com/photos/93171013@N08/8520549271/in/photostream/) almost touching the red area and not reporting anything.
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on March 16, 2013, 07:08:44 AM

PlayBASIC V1.64O - Doc Builder V0.80 Updated

   Been making some updates to the documentation and the documentation builder most of this week. The doc's are written in a kind of markup language that you'd find used in most forum software. The PB + UW web sites use a similar set of tags for the text. So text can be moved between sites without always having to reformat them for display.

  Some tags that sites use that doc's didn't would be things font sizing and colour tags. So if we dragged some text over from the forum into the doc's they'd have to be reformatted. Pretty tedious stuff, where it's easier to just drop some code into the document parser in the builder.

  The doc builder isn't updated very often, so when cracking open the project, it was soon obvious the parser was written to be quickly thrown to together, rather than easy to update. Most of the tags, it just use replaces$ statements on the raw text. Which is OK, but there are some situations where that approach fails (like when a tag contains a keyword another tag uses). So decided to write a more general purpose parser that new tags could be dropped into without logical problems.

  The updated solution scans through the document looking for tags, when it finds a possible tag it attempts to decode it. If it's a known, we call the response function, if not, ignore and keep scanning. The parser supports all the old stuff (mostly just cut'n'pasted into the new routine) like automatic cross referencing of local links, pictures, indentation, inner menus and syntax highlighting PlayBASIC code blocks, through to a hand full of new tags for Font sizes and color controls. Which just improve the styling of the information. And when there's 1276 pages of documentation, we need all the styling help we can get.

  Some other changes are better project copying support when building the manual. Previous versions would only copy projects with a single main source file. So example projects attached to articles can now have as many files as the author likes. Another addition that I can't believe hasn't made it's way into the tool sooner, is support for creation and edit dates within the articles. Which might not seem all that useful now, but we can finally track what articles are likely to be different between manual builds.

  Anyway all this stuff will appear in the V1.64O upgrade at some point.


Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on March 25, 2013, 12:13:38 PM
 PlayBASIC V1.64O - Docs Docs Docs

    Progress has been pretty slow on all fronts recently, still trying to wedge the odd documentation pass in wherever possible.   Most sessions seem to focused around running the global replacement tool over the various command sets.   The only problem with global replacements is they're indiscriminate.   Making It a bit of a skill catching the various typo combinations without breaking other sections.  The up side is that's pretty quick even though it's written in PlayBASIC classic. 

    It's not all about typo's though, there's a number of abbreviations that pop up throughout the manual, generally used within a hand full of variations.   So I've been trying to catch them where ever possible.   It actually needs some kind of glossary of terms also, just to keep it all self contained.    Ideally so when it's finally put online it'll get more links in, than out.     Some of that stuff could just be on the PB.com site though.   Lots of terminology being thrown around that apparently almost nobody understands.

   One thing the replacement tool doesn't handle though, is parsing the associated PlayBASIC examples that each articles may have.   The doc's are really just a series of folders, each folder is a command set/region of the manual.   Within each area, each command has it's own folder for it's attached projects.  The replacement tool only looks at the article though, it doesn't load and parse attached project also, in fact it has no ideas about this concept.   Meaning errors can't be trapped in the attached source files.

   Not 100% sure when it'll be ready,  but with the holidays fast approaching that should help things along.   Probably only a few more hour sessions in it..  We'll see..

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on March 26, 2013, 12:53:16 PM

PlayBASIC V1.64O  - Docs Update (Beta)

      Just put today's build on the docs of the help online.  There's a bit of new stuff hidden away in there, but basically it's had various replacement passes run over it.   Hopefully they haven't broken anything in process, but that's certainly possible.    Mainly interesting in broken examples, so if you could pick them and test them that'd be most helpful. 

     [plink]Get Documentation Update (http://www.underwaredesign.com/forums/index.php?topic=1238.0)[/plink]


Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on April 01, 2013, 03:01:30 PM
  Mapping Bits To Palette Indexes

   One by-product of the Spectrum emulator thread was call back to an even older idea for mapping bit groups out at palette mapped chunky pixels.   Translating 1 ->2 bit planar frame buffers from some legacy platforms like the Spectrum + C64 etc etc is bit of a mouth full for the runtime to handle, without 'building' a complete render solution.  It's not just legacy video hardware, but these little tidbits pop up when loading legacy file formats also. (Example (http://www.underwaredesign.com/forums/index.php?topic=4019.0)  Where all you're doing it taking a byte, and rendering a pixel out for each bit or pair of bits.  

   Now if speed is absolutely desirable, then generally i'd build jump table generator for such things.   Where each of the possible byte values is mapped to a hand rolled set of DOT commands.    This works pretty well, but even in the leanest inner loops there's still a lot of VM + pixel write overhead.    I suspect the majority of that could be removed by building a command will draw dots from a user defined palette, where it selects the colour by rolling and masking the bit pattern.   So you could render each bit as pixel or groups of bits as pixels.

   A bit like this,

[pbcode]


      Global PaletteAddress
      Dim Palette(256)
      PaletteAddress=GetArrayPtr(Palette(),true)


      Palette(0)=$ff0000
      Palette(1)=$ffffff
      Palette(2)=$00ffff
      Palette(3)=$0000ff

   t=timer()
   
      print "Single Pixel"
         Lockbuffer
            for lp=100 to 110 step 2
               PM_DOT_ROLBITMASKB(400,lp, %01111111,1,%00000001,8)
            next
         unLockbuffer


      print "Double Pixel"
      Lockbuffer
            for lp2=lp to lp+10 step 2
               PM_DOT_ROLBITMASKB(400,lp2, %00110110,2,%00000011,8)
            next
      unLockbuffer

   print timer()-t
   


   Sync
   waitkey
   

   ; -------------------------------------------------------------------
   ; ROR AND DRAW PALETTE MAPPED DOTS
   ; -------------------------------------------------------------------

Psub PM_DOT_ROLBITMASKB(Xpos,Ypos, ThisByte,ShiftDistant,Mask,RunLength)

   For lp=1 to RunLength   
         ThisByte=Rol8(ThisByte,ShiftDistant)
;         print bin$(ThisByte)

         col=Palette(ThisByte and Mask)
         ; Draw the dot 4 times it's actual size so we can see it
         Dotc Xpos  ,Ypos,col
         Dotc Xpos+1,Ypos,col
         Dotc Xpos+2,Ypos,col
         Dotc Xpos+3,Ypos,col

         Ypos2=Ypos+1
         Dotc Xpos  ,Ypos2,col
         Dotc Xpos+1,Ypos2,col
         Dotc Xpos+2,Ypos2,col
         Dotc Xpos+3,Ypos2,col

         Xpos+=4
   next

EndPsub

[/pbcode]

     A long & word sized palette version would be handy also, then you could palette map your sprites and encode/decode then in some bizarre format and load them without as much brute force overhead.  



[pbcode]

      Global PaletteAddress
      Dim Palette(256)
      PaletteAddress=GetArrayPtr(Palette(),true)


      Palette(0)=$ff0000
      Palette(1)=$ffffff
      Palette(2)=$00ffff
      Palette(3)=$0000ff

      
      Xpos =100

      For Chr=0 to 1
         Ypos=100
      
         Lockbuffer

            for ScanLine=0 to 7
               ThisByte=ReadData()   
               PM_DOT_ROLBITMASKB(Xpos,Ypos+(ScanLine*2), ThisByte,1,%00000001,8)
            next
         unLockbuffer

         Xpos+=8*4+10

      next      
      

   Sync
   waitkey
   


   ; -------------------------------------------------------------------
   ; ROR AND DRAW PALETTE MAPPED DOTS
   ; -------------------------------------------------------------------

Psub PM_DOT_ROLBITMASKB(Xpos,Ypos, ThisByte,ShiftDistant,Mask,RunLength)

   For lp=1 to RunLength   
         ThisByte=Rol8(ThisByte,ShiftDistant)
;         print bin$(ThisByte)

         col=Palette(ThisByte and Mask)
         ; Draw the dot 4 times it's actual size so we can see it
         Dotc Xpos  ,Ypos,col
         Dotc Xpos+1,Ypos,col
         Dotc Xpos+2,Ypos,col
         Dotc Xpos+3,Ypos,col

         Ypos2=Ypos+1
         Dotc Xpos  ,Ypos2,col
         Dotc Xpos+1,Ypos2,col
         Dotc Xpos+2,Ypos2,col
         Dotc Xpos+3,Ypos2,col

         Xpos+=4
   next

EndPsub


Memory:
   Data %11111110
   Data %10000001
   Data %10000001
   Data %10000001
   Data %11111110
   Data %10000000
   Data %10000000
   Data %10000000
   
   Data %11111110
   Data %10000001
   Data %10000011
   Data %11111100
   Data %11111100
   Data %10000011
   Data %10000001
   Data %11111110
   
[/pbcode]



 Couldn't help it..  A C64 mock up...  

      Dropped a bare bones version of the routines into PB, ripped the character set and quickly knocked up a C64 display emulation.  The screen is draw in 1by1 and scaled up to fit the screen a bit better.  Memories..


 Edit #1: Can almost double the performance of the naive version by fetching the character set bitmap in longs rather than bytes.   The size of the fetch is helpful in PB, but by caching the value in an integer and then scrolling the bits via division (quicker than a function call), we get a lower latency per 8 pixel strip.    Shown in the second picture.  

    So to render a 8*8 pixel square we end up with this,
[pbcode]

                        ThisLong=PeekBankInt(CharMapRomBank,Address)
                        Address+=4

                        VGFX_PM_DOT_RBMB(Xpos,Ypos2, ThisLong,1,%00000001,8)
                        Ypos2+=1
   
                        VGFX_PM_DOT_RBMB(Xpos,Ypos2, ThisLong/$100,1,%00000001,8)
                        Ypos2+=1

                        VGFX_PM_DOT_RBMB(Xpos,Ypos2, ThisLong/$10000,1,%00000001,8)
                        Ypos2+=1

                        VGFX_PM_DOT_RBMB(Xpos,Ypos2, ThisLong/$1000000,1,%00000001,8)
                        Ypos2+=1


                        ThisLong=PeekBankInt(CharMapRomBank,Address)
                        Address+=4

                        VGFX_PM_DOT_RBMB(Xpos,Ypos2, ThisLong,1,%00000001,8)
                        Ypos2+=1
   
                        VGFX_PM_DOT_RBMB(Xpos,Ypos2, ThisLong/$100,1,%00000001,8)
                        Ypos2+=1

                        VGFX_PM_DOT_RBMB(Xpos,Ypos2, ThisLong/$10000,1,%00000001,8)
                        Ypos2+=1

                        VGFX_PM_DOT_RBMB(Xpos,Ypos2, ThisLong/$1000000,1,%00000001,8)

[/pbcode]


  Edit #2: By pre-computing the vertical offsets per row, we squeeze another 20-25 odd fps out of such a refresh.   So the inner character rendering loop is down to approximately  18 or so PB VM  instruction calls per 64 pixels rendered.     Some of them optimize away, but it's a reasonable indicator.   Not all instructions execute in the same time though.   

[pbcode]

      rendertoimage screen
      Lockbuffer
      ThisRgb=Point(0,0)
      Ypos=0
      For ChrYLP =1 to 200/8
            Xpos =0

            Ypos1=Ypos
            Ypos2=Ypos+1
            Ypos3=Ypos+2
            Ypos4=Ypos+3
            Ypos5=Ypos+4
            Ypos6=Ypos+5
            Ypos7=Ypos+6
            Ypos8=Ypos+7

            For ChrXLP=1 to 320/8
                        ThisLong=PeekBankInt(CharMapRomBank,Address)
                        Address+=4

                        VGFX_PM_DOT_RBMB(Xpos,Ypos1, ThisLong,1,%00000001,8)
                        VGFX_PM_DOT_RBMB(Xpos,Ypos2, ThisLong/$100,1,%00000001,8)
                        VGFX_PM_DOT_RBMB(Xpos,Ypos3, ThisLong/$10000,1,%00000001,8)
                        VGFX_PM_DOT_RBMB(Xpos,Ypos4, ThisLong/$1000000,1,%00000001,8)

                        ThisLong=PeekBankInt(CharMapRomBank,Address)
                        Address+=4

                        VGFX_PM_DOT_RBMB(Xpos,Ypos5, ThisLong,1,%00000001,8)
                        VGFX_PM_DOT_RBMB(Xpos,Ypos6, ThisLong/$100,1,%00000001,8)
                        VGFX_PM_DOT_RBMB(Xpos,Ypos7, ThisLong/$10000,1,%00000001,8)
                        VGFX_PM_DOT_RBMB(Xpos,Ypos8, ThisLong/$1000000,1,%00000001,8)


               Xpos+=8
            next      
            Address&=$7ff  ; Keep Address within $7ff

         Ypos+=8
      next
      unLockbuffer

[/pbcode]



 
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on April 11, 2013, 11:00:00 AM

  PlayBASIC V1.64O  Beta 5- Dll Binding Tests

       In PlayBASIC we can use system & custom external DLL's in a handful of ways, from dynamically calling the functions (CallDLL) through to binding them (via LinkDLL) so they appear as if they're internal functions.    The latter is better solution since the function pointers are resolved before program execution starts.  When we use CallDLL, the operation has to solve the function pointer each call.    It's not a huge overhead, but an overhead none the less. 

       Using DLL's can have a few issues tho, most notably that windows doesn't provide a native 'load from memory'  functionality.  So  If you write a custom expansion dll, then you're basically giving this code away every time you share the final program.   In newer prototypes of the runtime we've solved this problem already,  but i've been wondering if it'd work in the legacy runtime at all ?  And Yes.. it does.. sort of :)

       So tonight's testing has been focusing on wedging the alternative loader layer into the runtime.  In the test any dll linked with linkdll, is pre loaded into a chunk of memory and then manually initialized for execution.  It's just defaulting to this behavior since it's the least amount of work required.   After a few little catch 22 hiccups the test dll's seems to be working as normal.

       Therefore, it appears that we should be able to bind custom dll's (dlls your program uses, NOT PB DLL's) into final EXE.    There's probably some DLL's where this won't work (like wrappers of wrappers), but ya get that !


Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: monkeybot on April 11, 2013, 04:11:22 PM
that sounds handy.i hope to actually get round to using it soon.
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on April 12, 2013, 10:27:47 PM

PlayBASIC V1.64O  Beta 5- Resource Manager

       Since DLL binding is working in the test, but there needs to be a system where the compiler/runtimes can attach/fetch linkdll resources as need be.  To do this, I've got to build a resource manager with searching facilities into the core.    Like most things, this turns out to be a little more work than i'd like, but the current incarnation seems to run pretty well (given limited testing).    Each resource has it's own name (string), rather than hard pointer, allowing high level services to query the resource buffer for media by name, before continuing on an loading the thing off disc if it's not present.    So in theory, pretty much anything could be attached and bundled in the same manner.

       Managing the resources at runtime is one part of the problem, but the resource buffers also need to be included the byte code hunk.  This is the point i'm at this afternoon, tentatively trying to solve some of the logic problems.   But i think we'll get there in some way, shape or form, even if the first solution isn't as clean as I'd like.       

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on April 14, 2013, 08:59:01 PM
   PlayBASIC V1.64O  Beta 5- Dll Resource Binding is a Go

         To paraphrase Murphy's law, anything that can go wrong, will go wrong..  and generally all at once.  So yesterday, we had some dramas with the server,  right while I was 1/2 way through sticking all the binding stuff together.    But eventually all the little dramas have been resolved.  

         Today's (well last nights) build of Beta 5, has binding up and running.  Allowing 3rd party dll's to be packed into EXE modules, and loaded/ initialized from  memory during compile and execution time also.     To do this, the programmer simply adds an asterix character to the start of the LInkDLL declaration and PB does the rest.  

        ie

[pbcode]

 ;  PlayBASIC expects to load this DLL from disc.  
linkdll "Test.dll"

   Myfunction() alias "NameInDll"
endlinkdll

   ; This tells PlayBASIC to import this dll as a resource
linkdll "*Test.dll"
   Myfunction() alias "NameInDll"

endlinkdll

[/pbcode]

     The only thing that I can see that's left to do, is try and drop some error messages in place of some of the little debug messages that can occur when somethings wrong.   Namely if the DLL you try and bind can't be found.  



  PlayBASIC V1.64O  Beta 5- Download

   Download   Removed, newer builds bellow



     
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on April 26, 2013, 12:50:57 AM
   More Testers Required !

    Just a reminder  that  we need more people upgrading to run the beta builds.  Currently only one person has bothered to download Beta 5 ( thanks for that), but really it defeats the purpose of having pubic beta testing.

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on April 28, 2013, 01:47:34 PM

   PlayBASIC V1.64O  Beta 6 - Replace$ Issue ?

        Everything has pretty much ground to a halt at the moment, as while testing the Amos To PlayBASIC conversion tool,  seem to be have uncovered a situation where Replace$ can fail.  At least that's what it seems like on the surface.  I'm more than a bit tentative pinning the blame on it as yet, after all, this is not my first rodeo and yesterday  I'd traced the same issue back to the split to array function.  These kind of issues are hard to track down and  I'm tentative because the functions might turn out to be ok, but the strings it's passing in could be damaged.   Which would definitely hang it, as the string engine assumes the VM always gives it are legal strings..   Either way something is looking fishy somewhere. 

        Another possible cause might be from man handling the arrays, the parser builds a tokenized view of the converted source code in nested types.  Where there's the program parent type, which in turn allocates it's own line buffer, where each line is a typed array.   Which not only means you can have as many programs in memory as need (I only actually need one),  but each line of code is a separate 1D typed array.  This removes the impact of moving lines and code fragments around.   Now when the convert routines parses the tokenize code, the routine skim through looking for the Tagged Tokens. if there's a match if runs the reaction function to the token.

         When changes need to be made to a line of code, it peeks into the array directly.    This allows the program to move stuff without every really knowing what it's moving and without having to copy the string fragments directly.   The thing is, when you start peeking and poke into an arrays memory, there's no "i think that'll work", it has to work correctly.  Otherwise you run the risk of either leaking the string/type resource your moving, or your function corrupts the array data in some way.   A leak would just have some information that was there, vanish so easy to track down (in most cases), but corruption can be bit more difficult.    If types were being leaked, then we've see parts of the output code would vanish from final code, but it's unlikely to cause some other function down the line to die.  Provided the bad routine that leaked that data, didn't insert a none existent thing into the line array.  If this occurs now we've a lottery, as the bad data might actually make sense in some causes,  but make it blow up in unexpected ways in others. 

         Anyway, while on the hunt have a found a few tidbits that were worth tweaking, but no smoking gun as yet.. well see.. 

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on April 29, 2013, 02:00:40 AM
   PlayBASIC V1.64O  Beta 6- Download

    Seem to have tracked the issue with replace$ down to the common string fragment searcher used in Replace/SplitToArray and possible other commands.  The problem was the matching could overflow the it's local stack,  Leading to all types of fun and games..    


   Download   removed, newer builds follow.



Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on May 14, 2013, 02:36:41 AM
  PlayBASIC V1.64O  Beta 7 - Boot Issues Resource Binding

    While the resource binding stuff was added a few revisions ago now, but it's not really been tested in the wild.  So wasn't that surprised to find some dependance dramas with attached dll's, in fact was expecting it.   The issued turned out to be the order in which the hunks are loaded.   If the function declarations are loaded before any bound Dlll they depend upon, then the address resolution will fail.. So the VM will exit when it runs into any function with a null address in user code.    Another issue could occur if default command bindings and the user bindings both had  resource hunks.  

    Been testing today's build Beta 7  with Amos-To-PlayBASIC and found another compiler dependency in the boot process on my 64bit Win7 system.   Turned out to be an easy fix, runs as normal now.   Not sure when that started but suspect the V1.64N revisions would have similar dramas in them but  haven't tested them.  No point now anyway.



 
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on May 16, 2013, 01:49:33 AM
 PlayBASIC V1.64O  Beta 9 - Tweaks & Things

        Been picking through the map level collision functions looking for an issue with RectHitLevel, initially seemed the query function was pulling the wrong 'spans' from level data, but after some head scratching it turns out the routine pop's a true on any block that has been classified as solid, regardless of if they overlap or not, as they may not.    Can't be sure, but are willing to bet there's some similar assumptions with other methods also.    Wouldn't mind updating the Mapping stuff again actually, not a huge fan of 'pixel level operations', as masks would be better.   Just not sure i can be bothered though.
 
       
       Edit:  Found another query problem with SpriteHitLevel when the sprites collision mode was set to mode 0.    
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on May 16, 2013, 09:13:53 PM

  PlayBASIC V1.64O  Beta 9b - Adding Errors

      By now you should realize that entire arrays can be passed around like candy, which allows us to do pretty wacky things.  However when we start doing this, the onus is largely put upon our shoulders, us that what we're writing into an Array, is actually a legal array, as it might not be.

      Ie.

[pbcode]

    Dim Stuff(100)

    ; assign Stuff() array to some none existent array
     Stuff() = 2000

[/pbcode]

     While PB would already precheck that the incoming value (on the right hand of the assignment) was actually an array container for us,  it would also ignore writes that weren't legal.   Making it harder to track down where the data corruption might be coming from.
 

[pbcode]

   Limbs=10

   Dim Tree(Limbs)
   MakeArray Branch()
   
   ; create an array to place them in the tree() array.
   ; so each cell is now conpetually a 1D array
   For lp =0 to Limbs
      
      ; The MakeBranchfunction exports the 'bank/container' of the array
      ; as an integer.  We can assign then anywhere.  There's nothing special
      ; about them. 
      
      
      Tree(lp)=MakeBranch(rndrange(5,20))   
   next

   ; Display the tree
   
   for lp=0 to limbs
      if Tree(lp)
   
         ; Copy the Branch array container into our redirection/pointer array
         ; so we now use the redirection arrays to look at the array data
         ; When PB writes the right handy value into Branch() array it check
         ; if this value does represent a legal array.  if it doesn't it'll error
         Branch()=Tree(lp)

         ; Parse the values into a string      
         Row$="Branch["+digits$(lp,2)+"] = "
         For b=0 to getarrayelements(branch())
            row$+=str$(Branch(b))+","            
         next
         
         ; print it out
         print trimright$(row$,",")
               
      
      endif
   
   next
   

   
   Sync
   waitkey



Function MakeBranch(Size)
   Dim ThisBranch(size)   
   For lp =0 to size
         ThisBranch(lp)=rnd(1000)
   next
EndFunction ThisBranch()


[/pbcode]


       

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on May 17, 2013, 02:01:19 AM
 PlayBASIC V1.64O  Beta 9b - Download

  removed, newer beta downloads follow.

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on May 26, 2013, 10:15:38 AM
  PlayBASIC V1.64O  Beta 9c - CRF tweaks

    Been looking into the CRF libraries the last few sessions.  The tweaks started out looking at the loading process, but have progressed to cleaning up the communication protocol between libraries and the legacy VM, plus a few more optimizations.  The clean up is a compromise really between the new and the old, but it removes some of the annoying set up work when sharing common resources between the VM with other libraries.   But I'll get more into that in some future blog.

    CRF formatted fonts have a couple of different flavors, namely 2, 8 or 32 bit.   Font's created using the interval commands will be 32bit if your converting a bitmap font,or mostly likely 8bit it's it's a GDI conversion.   While picking through some of the routines you can see's these a bit of generic meat on the bones so have trimmed a health slab of that fat out of some render combinations.    The one that's showing the biggest benefit would be the 8bit mode when blending to colour.   The previous edition seemed to be performing the blend every time a span was drawn.   Depending upon the situation, this is generally unnecessary, so can be pre computed.

    The result of the changes gives about 20-30% higher through put, which is more than handy.


[pbcode]

   size=48
   LoadFont "Verdana",2,size,0,8

   FontBlendColour 2,$00ff00

   ; Set output to pre blend pixels with FontBlendColour
   fontdrawmode 2,2

Do
      cls 255

      frames++
      startinterval(0)
      Page_Of_Text(2,$ffff0000)
      tt#+=Endinterval(0)
      
      print tt#/frames
   
   
      Sync
   loop   



Function Page_Of_Text(ThisFont,C)

   oldrgb=getink()
   OldFont =GetCurrentFont()
   SetFont ThisFont

   ink c
   
   For lp=asc("a") to asc("z")
      s$+=chr$(lp)
   next
   s$+=s$   ;+s$+s$

   lockbuffer
   For ylp=0 to GetScreenHeight() step 10
      text xpos,ylp,s$
   next
   unlockbuffer

   SetFont OldFont
   ink OldRgb
   
EndFunction

[/pbcode]



      Testing blend with colour in different depth surfaces

[pbcode]


   size=48
   LoadFont "Verdana",2,size,0,8

   FontBlendColour 2,$00ff00
   
   Screen=1   
   CreateFXimageEx Screen,800,600,32

   ; Set output to pre blend pixels with FontBlendColour
   fontdrawmode 2,2

   ; ------------------------------------------------------------------
   Do
   ; ------------------------------------------------------------------
         rendertoimage Screen
         cls 255

         frames++

         startinterval(0)
            Page_Of_Text(2,$ffff0000)
         tt#+=Endinterval(0)
      
         rendertoscreen
         drawimage Screen,0,0,false
         setcursor 0,0
         print tt#/frames
         print GetImageDepth(Screen)
   
         Sync
   loop   



Function Page_Of_Text(ThisFont,C)

   oldrgb=getink()
   OldFont =GetCurrentFont()
   SetFont ThisFont

   ink c
   
   For lp=asc("a") to asc("z")
      s$+=chr$(lp)
   next
   s$+=s$   ;+s$+s$

   lockbuffer
   For ylp=0 to GetScreenHeight() step 10
      text xpos,ylp,s$
   next
   unlockbuffer

   SetFont OldFont
   ink OldRgb
   
EndFunction

[/pbcode]





Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on May 28, 2013, 09:08:46 AM
  PlayBASIC V1.64O  Beta 11 - Loading CRF's directly from memory

        While looking through the CRF library I've added a way to load the font from memory rather than disc.   The following snippet loads a GDI font and saves it out into CRF format.  The program then  loads this file into a memory bank, then loads the font from the memory bank using the amended loadFont command.   Allowing font data to be stored in pack files, encrypted, crunched etc.     Ideally what i'd like to do, is implement some method where 'media' in general can be compiled into the exe's resource bindings.  Which is only partially possible legacy PB editions.  

[pbcode]

   Filename$="D:\TestCrf.crf"

   // Load a true type and convert it to CRF
   LoadFont  "verdana",20,75,0,8
   SaveFont Filename$,20
   deletefont 20
   
   
   // Load the file into a bank
   fh=ReadNewFile(filename$)
      size=filesize(filename$)
      Thisbank=NewBank(size)
      ptr=GetBankptr(thisBank)
      ReadMemory fh,Ptr,Size
   closefile fh
   

   // Load the front from memory.   Here instead of passing the load command
   // the filename with path, we give it the address of the resource in memory
   // in string form.  
   LoadFont "&"+str$(ptr),30,0   


   // This bank is no longer of any use, so delete it
   DeleteBank ThisBank
   
   
   // set and draw some text with the font loaded from memory
   setfont 30
   Print "Hello World"
   
   Sync
   waitkey

[/pbcode]
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on May 29, 2013, 08:53:31 AM
  PlayBASIC V1.64O  Beta 11b - Loading PNG images directly from memory

      So in keeping with yesterdays updating of the CRF loader, here we have a variation of the PNG loader.  Just like the CRF stuff we pass the LoadImage (or any of it's variants) the address as a string with the & prefix.    The only difference is that this time, the buffered image data needs a 4 header with the size of the image data in it.   I'm not too keen on it, but it seems unavoidable.

      Today's built only supports PNG's, since that loader was just fetching the data into memory to begin with, the other formats are a little more 'attached' to the disc interface.


[pbcode]

   Filename$="D:\PlayBAsicSig2.png"
 
  // Load the image file into a bank.  The picture data needs the size (of the image)
  // appended to the header of the structure for this work.  
  fh=ReadNewFile(filename$)
     size=filesize(filename$)
     Thisbank=NewBank(size+4)
     ptr=GetBankptr(thisBank)
   
      ; poke the size into the first 4 bytes
      pokebankint ThisBank,0,size

      ; read the data in after the size.  
     ReadMemory fh,Ptr+4,Size
  closefile fh
 

  // Load the image from memory.
  // Just like the LoadFont tests, here we pass the loadIMage command
  // the address of the buffer in memory.  
  LoadImage "&"+str$(ptr),100,8

  // This bank is no longer of any use, so delete it
  DeleteBank ThisBank
 
   cls 255
   drawimage 100,100,100,true
     
  Sync
  waitkey

[/pbcode]




  Loading Map Blocks directly from memory

       Since the Map library uses the image library to load media these days we're able to expose the functionality to loading blocks also.


[pbcode]


  Filename$="D:\PlayBasicSig2.png"
   
   // Load the image file into a bank.  The picture data needs the size (of the image)
   // appended to the header of the structure for this work.   

   fh=ReadNewFile(filename$)
      size=filesize(filename$)
      Thisbank=NewBank(size+4)
      ptr=GetBankptr(thisBank)
   
      ; poke the size into the first 4 bytes
      pokebankint ThisBank,0,size

      ; read the data in after the size. 
      ReadMemory fh,Ptr+4,Size
   closefile fh



   // Load the image from memory.
   // Just like the LoadFont tests, here we pass the loadIMage command
   // the address of the buffer in memory.   
      t=timer()
      LoadafxImage "&"+str$(ptr),100
   

      

      BlockWidth=32
      BlockHeight=32

      Map=NewMap(10)
      Level=NewLevel(Map,20,10)

      LoadMapGFX  "&"+str$(ptr),Map,BlockWidth,BlockHeight,-1,4
   
      Tile=0
      For ylp =0 to GetImageHeight(100) step BlockHeight
         For xlp =0 to GetImageWidth(100) step BlockWidth
               PokeLevelTile Map,Level,xlp/BlockWidth,ylp/BlockHeight,Tile
               Tile++
         next   
      next
         
      leveldrawmode map,level,2
      
      cls 255
      drawimage 100,100,100,true
         
      drawmap Map,level,100,300     
      
      
      DeleteBank ThisBank
      
   Sync
   waitkey

[/pbcode]



Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on May 31, 2013, 01:53:34 AM
  PlayBASIC V1.64O  Beta 11 - Download

   This revision includes the initial support of the LOAD MEDIA FROM MEMORY functionality.   The support thus far limits the user to loading PNG image files and CRF (Compressed raster Font) files from memory  (JPG/BMP/TGA are NOT supported).

   Come and get it..
     

    Download   removed, newer builds follow.


Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on June 01, 2013, 12:26:36 PM

  PlayBASIC V1.64O  Beta 12 - Loading BMP/TGA images directly from memory

       So tonight's little coding session adds load from memory support for BMP and TGA image formats.  From the limited testing it's had tonight, it all seems to be working pretty well.    When picking through the loader,  the easy solution just seemed to be replace the 'file' fetching commands with an ambiguous interface.   Which meant rolling a bit of extra set up code, but once that was done the decode logic is identical in both modes.

       Just like loading PNGs from  memory, the loader needs the size of the resource (in bytes) poked into the data header.    This is really in an effort to trap some load possible errors up front, but existing loaders don't really bother with errors too much.  Some formats will require it, others not so much.

       Anyway, what all this now allows you to do, is create custom pack files with at least the image media in them.     
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on June 03, 2013, 01:08:17 PM
  PlayBASIC V1.64O  Beta 12 - Download

   This revision rounds out the LOAD MEDIA FROM MEMORY functionality.   The support is limited to PNG,BMP,TGA + CRF.     (JPG isn't supported).

     

   Old Download deleted, newer downloads bellow.

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on June 04, 2013, 07:15:37 PM

  PlayBASIC V1.64O  Beta 13 - 32bit Power Of 2 and Black Optimizing

       Been taking a peek back into the texture map span rendering library, which is the core behind pretty much anything that's rotated.   Can't remember now, but at some point we added a hand full of short cut routines for some of common render modes.  So if the draw mode was 'simple' we call a dedicated routine to solve this.  This avoids having to falling through the multi pass filler, which is pretty flexible, but can be eat up some render time.

       Rotated Sprites are texture mapped quads in PlayBASIC,  when we draw a rotated image/texture map,  we're fetching pixels from texture in a none linear fashion.  So we  look up each texel (pixel in texture space) by interpolation down the polygon edges and across the strip.  The coordinates might be anywhere in the texture though.    Now since the texture can be any size, we need a multiply in the texel fetch to work out the where in memory the pixel actually is.  Knowing this, we added some power of two  render modes back during some other update.    Now when the mapper routine knows the source texture is a power of two (width), it calls a version of the filler than uses bit shifts rather than mults.    A bit shift is simply faster !   

       What this means is that if you're using image widths that are a nice round power of two, you'll get some extra speed for pretty much nothing.   Not only that, if the mask colour is zero (black = argb(0,0,0,0)), there's some combinations of the span filler that use this knowledge to it's advantage.   Since this allows the inner fill routine to avoid actually comparing texels with a user defined mask colour.  Winning us back some extra through put.   

        OK.. This is all old news, so tonight's little challenge has been to try and peel back the 32bit routines as much as possible with some interesting results.  This morning build of Beta 13 is rendering s the 500 (64*64) sprite test scene  around 20% faster than beta 12 (and older builds)  when the image is power of two and mask colour is zero.  Not only that actually slightly faster across the board.

        Here's the results from the bench mark.
       


--------------------------------------------------
Version:PlayBASIC V1.64O Beta 12
    Date:05 Jun 2013
   Image:gfx/ship.bmp
--------------------------------------------------
Test:1
Sprites[500] Rotated / Transparent=ON
Image=64*64 po2=1 MaskCOlour=0
Ticks=61250.1 Over=100 tests

Test:2
Sprites[500] Rotated / Transparent=OFF
Image=64*64 po2=1 MaskCOlour=0
Ticks=59431.68 Over=100 tests

Test:3
Sprites[500] Rotated / Transparent=ON
Image=64*64 po2=1 MaskCOlour=16711935
Ticks=59031.71 Over=100 tests

Test:4
Sprites[500] Rotated / Transparent=OFF
Image=64*64 po2=1 MaskCOlour=16711935
Ticks=58863.04 Over=100 tests

Test:5
Sprites[500] Rotated / Transparent=ON
Image=65*65 po2=0 MaskCOlour=0
Ticks=65830.69 Over=100 tests

Test:6
Sprites[500] Rotated / Transparent=OFF
Image=65*65 po2=0 MaskCOlour=0
Ticks=64011.32 Over=100 tests

Test:7
Sprites[500] Rotated / Transparent=ON
Image=65*65 po2=0 MaskCOlour=16711935
Ticks=71085.37 Over=100 tests

Test:8
Sprites[500] Rotated / Transparent=OFF
Image=65*65 po2=0 MaskCOlour=16711935
Ticks=64103.31 Over=100 tests



--------------------------------------------------
Version:PlayBASIC V1.64O Beta 13
    Date:05 Jun 2013
   Image:gfx/ship.bmp
--------------------------------------------------
Test:1
Sprites[500] Rotated / Transparent=ON
Image=64*64 po2=1 MaskCOlour=0
Ticks=48223.4 Over=100 tests

Test:2
Sprites[500] Rotated / Transparent=OFF
Image=64*64 po2=1 MaskCOlour=0
Ticks=58496.33 Over=100 tests

Test:3
Sprites[500] Rotated / Transparent=ON
Image=64*64 po2=1 MaskCOlour=16711935
Ticks=48894.36 Over=100 tests

Test:4
Sprites[500] Rotated / Transparent=OFF
Image=64*64 po2=1 MaskCOlour=16711935
Ticks=58264.08 Over=100 tests

Test:5
Sprites[500] Rotated / Transparent=ON
Image=65*65 po2=0 MaskCOlour=0
Ticks=64852.79 Over=100 tests

Test:6
Sprites[500] Rotated / Transparent=OFF
Image=65*65 po2=0 MaskCOlour=0
Ticks=62616.84 Over=100 tests

Test:7
Sprites[500] Rotated / Transparent=ON
Image=65*65 po2=0 MaskCOlour=16711935
Ticks=67575.52 Over=100 tests

Test:8
Sprites[500] Rotated / Transparent=OFF
Image=65*65 po2=0 MaskCOlour=16711935
Ticks=62693.11 Over=100 tests



       If you look closely you'll notice there's a pretty handy reduction in the first four tests when running in Beta13, which all come from the maskcolour and width of the texture is a power of two.   There's not much change in the general routine though (there is some).  Since $ff00ff is a commonly used mask, it might be viable to roll a few variations with that colour also.  Can't be sure, but I'd imagine they'd be somewhere in the middle.   

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on June 10, 2013, 05:03:29 PM
  PlayBASIC V1.64O  Beta 13 - Download

   Here's what's looking to be the final beta for the V1.64O  revision.    We strongly recommend you test it with your programs prior to the final is released.    

    Deleted,  Newer download bellow


Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on June 12, 2013, 01:05:49 AM

  PlayBASIC V1.64O  Beta 14 - Palette Mapping Library

        Earlier this update we looked at some methods for mapping groups of 8bits out as palette mapped pixels.   To test the theory,  an example showed how we can draw mock up commodore 64 screen in 'hires' mode.  But the process is not just the realm of emulation, as such conversions also occur loading/importing image data, 2bit & 4bit windows bitmap files come to mind.

        Since the initial tinker i'd been thinking of dropping some similar functions into a SLIB.  So far there's only four functions,  but they cater for the situations that come to mind.   So we've got a function to take a byte and couple of functions to render splits of bytes/words as palettes mapped horizontal strip.  There's not rect render as this point, but it's similar to something I was testing a number of years ago.   

        For those not sure what palette mapping is, well it's a bit of step back to the old days of 8bit graphics hardware.   A classic 8Bit screen mode, has up to 256 unique colours on screen ( 2^8=256 ) .    Most systems that had 8bit displays had 24bit RGB colours, much like today.   The difference is that rather than the screen representation being an array colours RGB values like it is today,  legacy hardware used a palette indexes.   So each pixel was a index into the palette array.   Each pixel index was one byte.   

       You can visual it like this,

[pbcode]

   Dim Palette(256)
   Dim Screen(320,200)

[/pbcode]

       So the hardware would read through the Screen() array, grab the each colour index value and use that value to read from the Palette to get output colour.   ie   OutputRGB =Palette( Screen(Xpos,Ypos))   

       Old systems used palette mapped images because they're very efficient (on memory and cpu).  For example, to draw graphics in 8bit,  the program only has to shift the colour index data in screen(),  which in an 8bit screen mode is 1/4 of we have push around today in 32bit modes.    The down side is that you're very limited in terms of colours.  You literally only have 256 colours to choose from on screen at once and it's difficult to remap/make them at runtime.    Some systems had ways around this (mutli plexing), but it's still pretty limiting.
 
       However, there's a number of neat effects you can do with palettes, probably the one most people are familiar with is colour cycling.  Which you'd often see used to convey motion in water/lava  sprites/pictures in retro games.   Ironically, now days we'd pretty much have to build an animation to achieve to the same thing. 

        Knowing this,  figured one easy way would be to use a function that's designed to take 8bit/16bit arrays and render them as if they're a normal strip/image.   So if you had a colour cycling fragment, you'd scroll the palette,  then render the fragment to a regular PB image and hey presto colour cycling.


        Here's an example of a routine to draw a palette mapped set of strips to an image.   The 8bit image data is just set up as runs of ascending values with the palette set up to scale up from, rgb(0,0,0) to rgb(255,255,255), so we get a  gradient of sorts.   I've randomly changed some of the pixels and the first few colours to make sure it's rendering correctly.

[pbcode]

// ----------------------------------------------------------------------------      
// ----------------------------------------------------------------------------      
Test_Palette_Mapped_Strips:  // (8bit palette map)
// ----------------------------------------------------------------------------      
// ----------------------------------------------------------------------------      

      rendertoimage screen
      Lockbuffer
      ThisRgb=Point(0,0)
      Ypos=0
      For ypos =0 to 255
            address=GetBankPtr(ScreenBank)+(ypos*320)
            DrawPaletteMappedStrip8(xpos,ypos,Address,320,$ff)
      next
      unLockbuffer

      return
      
[/pbcode]

     Speed wise it's fine,  the loop executes in about 1/2 a millisecond on my old desk top,   attached is a picture.     Was going to create some a little more interest to look at but couldn't be bothered..  :)

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: monkeybot on June 12, 2013, 12:57:34 PM
beta 13-No probs running lots of progs.

There are definite speed improvements.

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on June 13, 2013, 02:17:48 AM
  
QuoteThere are definite speed improvements.

   That's good to know.


  PlayBASIC V1.64O  Beta 14 - Palette Mapping Library Cont

        Ok.. so dropped some more functions into the palette mapping library and back end.   This is going to be pretty difficult to wrap your minds around, but in the demo bellow we're loading RGB mapped images, converted them to a global palette which is 16bit in size. This gives us a 2^16 possible colours that be used.  The colours can still be 32bit.     Now since we're using 16bit palette, we need to force the loaded images to be 16bit 656 format.  We do this using the CReateFXimagfeEX command.  Which allows you to create an image of any depth (pixel format), regardless of the screen mode.     Then a conversion routine replaces the RGB colour with the palette indexes in the image.

        Now if we create a 'screen' image that's the same depth as the palette mapped sprites (16bit),  we can use the normal image rendering stuff in PlayBASIC to draw them to the conceptually palette mapped buffer.  Once we're done rendering, we draw the screen out as a group of palette mapped strips.     This gives us a 32bit end result, but we've halved the amount of bandwidth that's moved around in the picture.    Plus you can modify the palette.    Raster Bars, Colour cycling  etc

         Here's  a demo showing the basic approach,  the palette mapped scene is actually fading in/out in this demo.  Fading a Palette mapped mode is much less work, since we only have to scale the palette RGB's and not every single pixel.   

[pbcode]

      #include "PaletteMapping"

      loadFont "verdana",2,24,0,8


      Dim Palette($10000)
      Dim MasterPalette($10000)
      SetPalette(Palette())

      ; set colour zero as RGB(0,0,0), since the images use that colour as transparent
      Palette(0)   = $00000000
      ColourCount=1


      ; create 16bit fX image as the palette mapped screen..
      Screen=CreateScreen(800,600)      
   

      ; load some images and remap the RGBS to palette indexes
      Ship,ColourCount= LoadAsPaletteMappedImage("gfx\ship.bmp",Palette(),ColourCount)
      Bubble,ColourCount= LoadAsPaletteMappedImage("gfx\bubble_64x64.bmp",Palette(),ColourCount)
      Logo,ColourCount= LoadAsPaletteMappedImage("gfx\uwlogo.bmp",Palette(),ColourCount)
      
      
      // Make a copy of the original palette
      CopyArray Palette(),MasterPalette()
      
      
      
            
      Do      
   
         cls 255
      
         frames++

         setcursor 0,0

         t=timer()

         // -----------------------------------------------
         // draw to the 16bit screen
         // -----------------------------------------------
         
            rendertoimage Screen
            cls 0   
            
            gridimage   Ship,mousex()-250,mousey()-250,10,10,true
         
            drawrotatedimage Bubble,400,100,angle#,2,2,-32,-32,true
            angle#=wrapangle(angle#+2)
         
            drawimage logo,100,200,true         
         
            rendertoscreen         
         
            // draw the palette mapped buffer to actual screen
            RenderScreen(Screen,Xpos,Ypos,Palette())
         tt#+=Timer()-t


         // -----------------------------------------------
         // draw what the sprites to
         // -----------------------------------------------
         drawimage ship,0,500,true
         drawimage bubble,64,500,true


         setfont 2
         lockbuffer
            print "Screen Resolution:"+Str$(GetImageWidth(Screen))+"*"+Str$(GetImageHeight(Screen))
            print "Palette Size:"+str$(ColourCount)
            print "Ticks:"+str$(tt#/frames)
            print "Fps:"+str$(fps())
         unlockbuffer



         // --------------------------------------
         // Fade palette in and out      
         // --------------------------------------
            ScaleLevel=128+Cos(angle#)*128
            ScaleLevel=ClipRange(ScaleLevel,0,255)
            
            For lp=0 to ColourCount   
                  ThisRgb=MasterPalette(lp)
                  Palette(lp)=RgbScale(ThisRgb,ScaleLevel)
            next
            
         Sync
      loop
   



Psub CreateScreen(Width,Height)
      ; the
      local ThisIMage=GetFreeImage()
      CreateFXImageEx ThisImage,Width,Height,16
EndPsub ThisImage

   
   
   
Psub RenderScreen(Screen,Xpos,Ypos,Palette())
   if GetImageStatus(Screen) and Screen>0

      if GetImageDepth(Screen)=16

         SetPalette(Palette())

         oldSurface=GetSurface()

         rendertoimage Screen   
         lockbuffer
            thisrgb=point(0,0)
            Width   =GetImageWidth(Screen)
            HEight=GetImageHeight(Screen)
            Ptr   =GetImageptr(Screen)
            Modulo=GetImagePitch(Screen)
         unlockbuffer

         rendertoimage OldSurface

         lockbuffer      
            thisrgb=point(0,0)
            For ypos =0 to Height-1
                  DrawPaletteMappedStrip16(0,ypos,Ptr,Width,$ffff)
                  ptr+=Modulo
            next
         unLockbuffer
      endif

   endif
      
EndPsub





Psub LoadAsPaletteMappedImage(File$,Palette(),ColourCount)

      local TempImage=LoadNewImage(File$,2)

      local w=GetIMageWidth(TempImage)
      local h=GetIMageHeight(TempImage)

      local ThisImage=GetFreeImage()
      CreatefxImageEx ThisImage,w,h,16

      ColourCount=PaletteMapRGBImage(TempImage,Palette(),ColourCount)

      copyrect TEmpImage,0,0,w,h,ThisImage,0,0

      deleteimage tempimage   
EndPsub ThisImage,COlourCount

[/pbcode]
         

     So bellow we have a shot of what this looks like running..   In the bottom left hand corner you can see the palette mapped SHIP/BUBBLE images drawn directly to screen.  The pixel data in them is no longer RGB's  colour values, but INDEX into the palette array.  So they look all crazy now when drawn to to the normal display..

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on June 13, 2013, 09:15:08 PM
  PlayBASIC V1.64O  Beta 14 - Palette Mapping Library Cont #2

     Continued tweaking the library ideas so the following is more a proof of concept.   Previously we had a pretty shallow palette (1200 colour or so),  so I wanted to test out something a bit bigger.   Soon found the Missile Attack  backdrop which is 800*600.   The only issue with converting it, is that the routine the palette maps image data isn't very quick (nested linear searching).  In particular when the image is mostly unique colours like this one,  so it can a take few seconds to map that image..

     Drawing the scene is same as normal, it's a 16bit blit of the palette mapping background to the 16bit screen.  Since there's no pixel format conversions it ends up as a pure memory copy.. What's interesting though, is that you can draw a good 10 layers of 100 transparent images over the top.   Which can rotate also.   What you couldn't do (at least without setting up the palette in very particular way) is blend or filter them.  Since those actions would treat the individual texels in the sprites as  RGB channels and not Indexes, so the mixing them would create all sorts of funky results..   I'll bet there's some very interesting effects that are just waiting to be discovered because of that however.  

     Since the palette data in the test scene is now pretty large (50K colours), sitting in a for/next loop tinting all those colours individually is a lot of dead weight.   So one easy way around this is to the use the BlitImage  functions to do the tinting for us.   To do this, we make a image (32bit) (CreateFxImageEX), plot the palette colours in linear order (from 0 to $ffff).   This gives us a chunk of memory that contains the palette that we blend with.   So just make a second image (same size + depth)  and then blit it across.  This takes advantage of parallel mutilations available in the BlitImage functions.  You could even thread it.  

       
[pbcode]

      #Include "BlitImage"
      #include "PaletteMapping"

      loadFont "verdana",2,24,0

      Dim Palette($10000)
      SetPalette(Palette())

      ; set colour zero as RGB(0,0,0), since the images use that colour as transparent
      Palette(0)   = $00000000
      ColourCount=1


      ; create 16bit fX image..
      Screen=CreateScreen(800,600)      
   
      print "Palette Mapping Images (slow).. "
      sync

      ; load some images and remap the RGBS to palette indexes
      Layer,ColourCount   = LoadAsPaletteMappedImage("gfx\layer1.bmp",Palette(),ColourCount)
      Ship,ColourCount   = LoadAsPaletteMappedImage("gfx\ship.bmp",Palette(),ColourCount)
      Bubble,ColourCount= LoadAsPaletteMappedImage("gfx\bubble_64x64.bmp",Palette(),ColourCount)
      Logo,ColourCount   = LoadAsPaletteMappedImage("gfx\uwlogo.bmp",Palette(),ColourCount)
      

      // Store the Palette Data in an 32bit (256*256) image      
      MasterPaletteImage=MakePaletteIMage(Palette())

      // Make a clone of this image, so we can use blitimage functions to scale the palatte values
      PaletteImage=GetFreeImage()
      Copyimage MasterPaletteImage,PaletteImage
      
      
      // --------------------------------------------------------------------
      // --------------------------------------------------------------------
            
      Do      
   
         frames++

         setcursor 0,0

         t=timer()

         // -----------------------------------------------
         // draw to the 16bit screen
         // -----------------------------------------------
         
            rendertoimage Screen
            drawimage layer,0,0,false
                     
            x=mousex()-250
            y=mousey()-250
            For lp=0 to 199 step 10
               gridimage   Ship,x+lp,y+lp,10,10,true
            next
                  
            drawrotatedimage Bubble,400,100,angle#,2,2,-32,-32,true
            angle#=wrapangle(angle#+2)
         
            drawimage logo,100,200,true         
         
            rendertoscreen         
         
            // draw the palette mapped buffer to actual screen
            RenderScreenUserPalette(Screen,Xpos,Ypos,GetImagePtr(PaletteImage))
         tt#+=Timer()-t
         

         // -----------------------------------------------
         // draw what the images artual contain
         // -----------------------------------------------
         if spacekey()
            drawimage ship,0,500,true
            drawimage bubble,64,500,true
            drawimage PaletteIMage,GetScreenWidth()-256,GetSCreenHeight()-256,false
         endif

         setfont 2
         lockbuffer
            print "Screen Resolution:"+Str$(GetImageWidth(Screen))+"*"+Str$(GetImageHeight(Screen))
            print "Palette Size:"+str$(ColourCount)
            print "Ticks:"+str$(tt#/frames)
            print "Fps:"+str$(fps())
         unlockbuffer



         // --------------------------------------
         // Fade palette in and out      
         // --------------------------------------
            ScaleLevel=128+Cos(angle#)*128
            ScaleLevel=ClipRange(ScaleLevel,0,255)
            
            
            // Copy the Master palette image over the palette image with TINT applied
            rendertoimage PaletteImage
            BlitImageAlphaMultColour(MasterPaletteImage,0,0,rgb(scalelevel,scalelevel,scalelevel))
            rendertoscreen
            
            
         Sync
      loop
   




Psub CreateScreen(Width,Height)
      ; the
      local ThisIMage=GetFreeImage()
      CreateFXImageEx ThisImage,Width,Height,16
EndPsub ThisImage

   
   
   
Psub RenderScreen(Screen,Xpos,Ypos,Palette())
      PalettePtr=GetarrayPtr(Palette(),true)
      RenderScreenUSerPalette(Screen,Xpos,Ypos,PalettePtr)
EndPsub




Psub RenderScreenUSerPalette(Screen,Xpos,Ypos,PalettePtr)
   if GetImageStatus(Screen) and Screen>0

      if GetImageDepth(Screen)=16

         SetPalettePtr PalettePtr
         
         oldSurface=GetSurface()

         rendertoimage Screen   
         lockbuffer
            thisrgb=point(0,0)
            Width   =GetImageWidth(Screen)
            HEight=GetImageHeight(Screen)
            Ptr   =GetImageptr(Screen)
            Modulo=GetImagePitch(Screen)
         unlockbuffer

         rendertoimage OldSurface

         lockbuffer      
            thisrgb=point(0,0)
            For ypos =0 to Height-1
                  DrawPaletteMappedStrip16(0,ypos,Ptr,Width,$ffff)
                  ptr+=Modulo
            next
         unLockbuffer
      endif

   endif
      
EndPsub




Psub LoadAsPaletteMappedImage(File$,Palette(),ColourCount)
      local TempImage=LoadNewImage(File$,2)
      local w         =GetIMageWidth(TempImage)
      local h         =GetIMageHeight(TempImage)
      local ThisImage=GetFreeImage()
      CreatefxImageEx ThisImage,w,h,16
      ColourCount=PaletteMapRGBImage(TempImage,Palette(),ColourCount)
      copyrect TEmpImage,0,0,w,h,ThisImage,0,0
      deleteimage tempimage   
EndPsub ThisImage,COlourCount




Function MakePaletteIMage(Palette())
      Size=GetArrayElements(Palette(),1)
      if Size>$ffff
         oldimage=getsurface()
         ThisImage=GetFreeImage()
         CreateFXImageex Thisimage,256,256,32
         rendertoimage ThisImage
         lockbuffer
         ThisRGB=point(0,0)
         for ylp =0 to 255
            For xlp =0 to 255
                  fastDot xlp,ylp,Palette(Index)                        
                  index++
            next
         next
         unlockbuffer
         rendertoimage oldsurface
      endif
EndFunction ThisImage

[/pbcode]
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on June 14, 2013, 10:58:12 PM
   PlayBASIC V1.64O  Beta 14 - Download

     Here's beta 14, this version includes the updated palette mapping functions..   Which create a number of interesting possibilities for those creative programmers out there.  

 Download Deleted, newer build bellow.

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: micky4fun on June 16, 2013, 10:20:55 AM
yep beta14 fine here
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on June 16, 2013, 09:13:16 PM
  Palette Mapping -> PlayBASIC Image Format ?

        Been messing around the palette mapping routines a bit over the weekend,  mainly trying a few different ways to map larger images quicker.   The current built in solution is a naive solution, that is,  it assumes the image is full of mostly repeated colours.   So it's ok for images with a few colours, but execution time soon blows out when there's lots of colours in the image.

        The core problem with the existing routine is there's lots of dead overhead from the nested linear searching.   Obviously a better solution is to build a structure that's more efficient to search.  One approach is to arrange the colours  so they can be searched quicker, which means keeping the RGBS sorted.    To test the theory, wrote an emulation of the process in regular PlayBASIC code.     So the routine loads the image as normal, then runs though and sorts every pixels RGB value during the first pass, then we compute the indexes from the sorted data.    Being legacy PlayBASIC code, it's slower then existing native built in solution, but not by much..  Which tells us that the method is far more efficient than a built in brute force solution will ever be.    

        One of the most interesting byproducts of the palette mapped images, is the index and rgb table data are pretty compression friendly.   I've been testing a wall paper image that was from somebodies demo,  where the image is 1200*600*32bit pixels.   In BMP format it's 2,813K on disc,  in PNG format it's 935K on disc.     If we take this image and run it through the process above, the resulting none compressed file is 1558K on disc.  

      But when we zip the files,  we get this

      Zipped Palette Mapped (1558k) =  756k

      Zipped BMP (2813k) =  887k

      Zipped PNG (935k) =  934k
 

      So we're getting about a 20% saving in distributing size of the media,  which is a pretty significant saving and has been repeated over a number of test images now.  One further byproduct is there's little to no decompression cost at runtime since the data is raw and in order.  So the chunk is loaded to a buffer and 'drawn' to the destination surface as is, much like a none compressed BMP.   Pngs have to be loaded, decompressed, copied to the target.   I suspect it'd be about the same in real world speed terms.    

      What you could do is roll your own palette mapped image format.  Just load the image, map it and save out the palette and colour index arrays into a file.   Then write a loader to pull the whole file into memory, grab a pointer to the palette and pointer to the index array and draw  the strips to your target surface.   Which you can already this in the Beta 14 above.   Provided your images don't exceed  $10000 (2^16) unique colours that will work fine.   Those with a bit of imagination, will be able to roll their own pack files in a custom format and be able to drive down the distribution size beyond the rest of us..    


       For a long time now, i've been testing various methods that could be used for a PlayBASIC Image Format.  This is handy as PB specific data can stored in the image and restored upon load.  The focus being the format is easy to load into memory while being fairly efficient as possible.    While it might not turn out to be this particular form, supporting a variations of it would be more than useful.


      Update:

       The conversion routine has two main bottle necks, sorting the RGB values and searching the table for matches.    Have moved the sorting & searching into PB, and as expected it's about 10 times (or more) quicker than the brute force solution.  Which is about what i'd expected.    Bellow though the test is running on a 1200*600 sized image.   To test a theory, the sorting in this version is actually just regular PlayBASIC code where the sort routine has been tweaked to use least number of operations per loop.  In this example it's sorting 720,000 values, which is down to around 1750 milliseconds now, which is about 500 or so faster than it was.

       Anyway the attached is piccy of the demo, where it loads the regular image, palette maps it, saves,reloads and displays it.  The display version is scaled down to fit on screen.



  EDIT:  See-> PlayBASIC Image (PBI) Format Development Blog (http://www.underwaredesign.com/forums/index.php?topic=4329.0)

         
 
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on June 23, 2013, 09:23:20 AM
   PlayBASIC V1.64O  Beta 15 - Palette Mapping Round 3

       Been messing around with the palette mapping routines in PB and in the engine, coming up with a better method is always pretty satisfying, in particular when you can get the vanilla PB implementation that runs  quicker than the original brute force version in C.    To map the mountain image the original routine was taking 16->17 seconds.  The alternative version in standard PB does the same job in 3.7 seconds.    Had a feeling the newer method would be faster, but wasn't expecting that.   So by applying the rule of 10, then the same logic  in C should run in about 370 milliseconds,  which wasn't too far off, but It was more like 450.

        But, there's a but.... it's actually not the same method.    The original routine would map all incoming images into a global palette, where as the alternative method just works out the palette for this image.  Which is handy for say image compression, but doesn't slot into what we already had and coming up with a variation on the same theme that was fast, wasn't initially forthcoming.   Luckily while out on the bike,  came up with a reordering/splicing idea to shuffle the new images unique colours into the existing palette and when combined with an idea to cull the original RGB colours as much as possible, the final solution is about 3-times faster again.   Where it's now able to Palette Map the previous demo scene now in 130/140 milliseconds.  

       The interesting thing about this implementation is it gives you 2^16 unqiue 32bit colours within the frame, unlike an 2^8 screen mode in VGA/VSGA / AGA  graphics hardware.      Those with a little bit of creativity will no doubt discover ways of expanding the colour count way beyond that.  


   Related Articles:

    * Palette Mapped / Raster Bar Examples / Glenz Vector Example (http://www.underwaredesign.com/forums/index.php?topic=4060.0)

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on June 24, 2013, 10:10:36 PM
   PlayBASIC V1.64O  Beta 15 - Download

     Here's beta 15, this one includes the updated palette mapping stuff and a MOD fix.

 Download Deleted newer build bellow.
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on July 01, 2013, 02:13:19 AM
   PlayBASIC V1.64O  Beta 16 - ZClipper

     This one adds another mini slib library that handles clipping 3D rays down the z axis.

[pbcode]


   #include "zclipper"

   Projection#=500

   Texture=LoadNewIMage("tile.png",2)

   x1   =100
   y1   =500
   z1   =2500
      
   x2   =x1+500
   y2   =y1
   z2   =250

   depth =600
   
   Dim Vert0 as Zclipper_Vertex_Structure pointer
   Dim Vert1 as Zclipper_Vertex_Structure pointer
   Dim Vert2 as Zclipper_Vertex_Structure pointer
   
   Vert0 =ZClipVertexPtr(0)
   Vert1 =ZClipVertexPtr(1)
   Vert2 =ZClipVertexPtr(2)
   
   
   ClipPlane=900
   
   ClipMode=1
   
   Do

      cls 0
      
         print "Clip depth:"+Str$(ClipPLane)

      //
         z=depth+z1      
         px1 = (x1*Projection#)/z   
         py1 = (y1*Projection#)/z
         
         // Colour of the polygon         
         c1=Rgb(10,20,30)
         c2=Rgb(255,255,255)

         // uv coordinates         
         u1=0
         v1=0
         
         u2=GetImageWidth(texture)
         v2=0

         v3=GetImageHeight(texture)
         v4=v3
         
      //
         z=(Depth+z2)
         px2 = (x2*Projection#)/z
         py2 = (y2*Projection#)/z
         
         if (Depth+z2) < ClipPlane
            if (Depth+z1) >= ClipPlane

                  // intt a pair of vertex
                  ZClipSetVertex(0,px1, py1,x1,y1,depth+z1,Rgb(10,20,30),U1,V1)
                  ZClipSetVertex(1,px2, py2,x2,y2,depth+z2,Rgb(255,255,255),U2,V2)

                  // Clip the vertex pair 0 to 1 and store the result in vertex 2
                  ZClipRay(ClipPlane,0,1,2)

                  // Project the clipped point into 2d space
                  px2 = (vert2.WorldX*Projection#)/vert2.Worldz   
                  py2 = (vert2.WorldY*Projection#)/vert2.Worldz

                  // get the clipped U/V coords
                  u2  = vert2.u
                  v2  = vert2.v

                  c2  = vert2.thisARGb            
            
                  print "Clipped Vertx2"
         
            else
               print "Behind camera"            
               goto DontDraw            
            endif
            
         endif


         // draw these in screen space

         texturequad Texture, px1+100,300+py1, u1,v1,   px2+100,300+py2, u2,v2,_
                              px2+100,300-py2 ,u2,v3,   px1+100,300-py1, u1, v4, 0

         gouraudquad  px1+500,300+py1, c1,   px2+500,300+py2, c2,_
                              px2+500,300-py2,  c2,   px1+500,300-py1, c1
                              

         line px1+500,300+py1,px2+500,300+py2
         line px1+500,300-py1,px2+500,300-py2


DontDraw:

         print z1
         print z2
         print depth
         print u1
         print u2
         
         print Hex$(c1)
         print Hex$(c2)
         
         if UpKey()
               Depth-=1
         endif

         if downKey()
               Depth+=1
         endif

      Sync
   loop

[/pbcode]


 Download

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

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on July 04, 2013, 12:58:32 AM
   PlayBASIC V1.64O  Beta 16b - Cross Product Functions

    Dropped in a couple of crossproduct functions in to see how they perform against doing the same thing manually.   In the test code there's about a 30% gain on expressions that containing all floats when calling the float version, and about 10% gain on of integer version.   They're both faster so we'll leave those in.  

[pbcode]

   x1#=100
   y1#=100
   
   x2#=300
   y2#=150

   x3#=200
   y3#=300


   x1=x1#+400
   y1=y1#

   x2=x2#+400
   y2=y2#

   x3=x3#+400
   y3=y3#

   max=5000


do
      cls 0
      
      frames++

      // Float Versions
      print "[ Float Tests ]==================================="
      ts=startinterval(0)
      For lp =0 to max
                  result#=(((x2#-x1#)*(y3#-y1#))-((x3#-x1#)*(y2#-y1#)))
      next                 
      tt1#+=Endinterval(0)
      print result#


      ts=startinterval(0)
      For lp =0 to max
                  result#=CrossProduct#(X1#, Y1#,x2#,y2#,x3#,y3#)   
      next                 
      tt2#+=Endinterval(0)
      print result#
      
      
      print tt1#/frames
      print tt2#/frames
      

      print "[ Integer Tests ]==================================="


      ts=startinterval(0)
      For lp =0 to max
                  result=(((x2-x1)*(y3-y1))-((x3-x1)*(y2-y1)))
      next                 
      tt3#+=Endinterval(0)
      print result


      ts=startinterval(0)
      For lp =0 to max
                  result=CrossProduct(X1, Y1,x2,y2,x3,y3)   
      next                 
      tt4#+=Endinterval(0)
      print result
      

      print tt3#/frames
      print tt4#/frames


      line X1#, Y1#,x2#,y2#
      line x2#,y2#,x3#,y3#
      line x3#,y3#,x1#,y1#
      
      line X1,Y1,x2,y2
      line x2,y2,x3,y3
      line x3,y3,x1,y1
         
      print fps()
      Sync   
loop

[/pbcode]



  Tutorial On CrossProduct
 


 

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on July 05, 2013, 01:23:51 AM

  PlayBASIC V1.64O - Resource Binding

       Been stewing on this for a few weeks now and aren't really any closer to an ideal situation.  My preferred solution would see minimal changes to user code when the 'media' is bound into the final exe or loaded from disc.   So a line code like loadimage "gfx\MyPicture.png",1   would work regardless of the context.   If the media is bound into the EXE then the loader process and find this file as an internal resource and load it from memory, if it's not, it attempts to load it from disc.     Which is about as simple as I can make it. 

       But.... there's a but, which comes down to how the programmer tells PlayBASIC to construct the internal binding.    It can't work this from the user code, since anything that's not an literal is virtually impossible to compute at compile time.

     Ie.
[pbcode]
     
      For frame=1 to 10
              LoadIMage "gfx\ship"+str$(frame)+".bmp", 100+frame
      next

[/pbcode]
           
      With some messing around you could solve that at compile time, but all it takes is one external unknown and your toast.    So it becomes necessary to tell the compiler what files to bind and what not to bind into the exe.      The lazy solution is to have  recursive include function, that will grab everything in the folder and attached it.   That's a pretty naive solution as users would doubt end with distributing files they had never intended. 

      There needs to be some flexibility in the approach as  binding isn't necessarily just for image files, data files could also be attached.  Those would have to be handled differently for the user than just a loadimage command,  so it introduces another little twist into the process.   It's not uncommon for IDE's to have a 'resource managers' built into them today.   Obviously we can't do that today with PlayWrite, but you could have a tool that does something like that.   So rather than binding the 'files + folders' by hand,  you just attach the previously created pack file.

     Something  to think about anyway.     

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on July 06, 2013, 02:31:12 AM
   PlayBASIC V1.64O Beta 17 - Resource Binding Library

        So another session on and we're a bare bones implementation of data binding.   To handle the binding we use the #AddResource  directive followed by a literal string containing the file name (and path).   It's pretty dumb as this point as it only allows files to be bound individually.   This occurs during compile time currently so any time it sees the #AddResource directive it loads that media into memory.     The file is loaded as is, it doesn't understand the file, it's just being considered as pure chunk of data.

        Binding is one thing, using them other problem.   To help out, i'm throwing together some high level functions to grab/copy resources in particular way.  These will most likely be a as string, as bank, or as image if it's a image media type.   To query a resource we use it's imported filename.  This is a bit iffy, but it fits perfectly into how this embeds, so ya get that.  

        The example code bellow, imports a text file into the program memory (and the final exe when built).   To access the resource data in our program we use LoadResourceAsString$ function.   The query functions use the index of the resource, rather than the name.  There's FindResourceIndex(Name$) to find the index of the media in the table.  

    Example Usage:

[pbcode]

   Constant TextFile$="Files/Hello-World.txt"

   #AddResource TextFile$

   ; Find this resources index , indexes range between zero and number of bound resources in the program
   index=FindResourceIndex(TextFile$)
   if index>-1

      ; load the text file resource as string   
      s$=LoadResourceAsString$(Index)

      ; split the string into this array
      dim rows$(0)
      s$=replace$(s$,chr$(13),"")
      count=splittoarray(S$,chr$(10),Rows$())

      ; dump it to the screen
      for lp =0 to Count
         print rows$(lp)
      next
   
   endif

   
   Sync
   WaitKey

[/pbcode]


    Example Text File:



---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
Hello World

This is some text that's been loaded into the app and treated as an in memory resource.  

This is some text that's been loaded into the app and treated as an in memory resource.  
This is some text that's been loaded into the app and treated as an in memory resource.  
This is some text that's been loaded into the app and treated as an in memory resource.  
This is some text that's been loaded into the app and treated as an in memory resource.  
This is some text that's been loaded into the app and treated as an in memory resource.  
This is some text that's been loaded into the app and treated as an in memory resource.  
This is some text that's been loaded into the app and treated as an in memory resource.  
This is some text that's been loaded into the app and treated as an in memory resource.  
This is some text that's been loaded into the app and treated as an in memory resource.  
This is some text that's been loaded into the app and treated as an in memory resource.  
This is some text that's been loaded into the app and treated as an in memory resource.  
This is some text that's been loaded into the app and treated as an in memory resource.  

---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
 End of this file  is here
---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------




Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on July 06, 2013, 10:37:29 PM
  PlayBASIC V1.64O Beta 17 - Resource Binding Library #2

       Dropped a few more test functions last night,  was going to add them all as internal bindings, but might split them in two and have the core stuff bound and the helper functions as a library.   Since the helpers are extra bits and aren't always needed.   So far we're got some functions that will load bound materials in as PB media as images and fonts.  Since you can do this manually you can modify the resource before you use it.  Which might be some form of simple decompression, decryption etc etc.      

      In this example we're binding the a text file, PNG and CRF font into EXE memory and then loading them directly on demand, without ever needing to save them out to disc.  

[pbcode]

   Constant TextFile$="Files/Hello-World.txt"

   #AddResource TextFile$
   #AddResource "Files/Uwlogo.png"
   #AddResource "Files/Arial36.crf"


   ; Find this resources index , indexes range between zero and number of bound resources in the program
   index=FindResourceIndex(TextFile$)
   if index>-1

      ; load the text file resource as string   
      s$=LoadResourceAsString$(Index)

      ; split the string and remove chr 13's
      dim rows$(0)
      s$=replace$(s$,chr$(13),"")
      count=splittoarray(S$,chr$(10),Rows$())

      ; dump it to the screen
      for lp =0 to Count
         print rows$(lp)
      next
      
      ThisBank=LoadResourceAsBank(Index)
      
      Print ThisBank
      For lp =0 to GetBankSize(ThisBank)-1
            print PeekBankByte(ThisBank,lp)      
            #print chr$(PeekBankByte(ThisBank,lp))      
      next

   endif

   ThisImage=LoadResourceImage("Files/Uwlogo.png")

   drawimage ThisIMage,400,300,false
   
   ThisFont =LoadResourceFont("Files/Arial36.crf")
   
   setfont ThisFont
   
   
   text 200,200,"YEAH"
   
   Sync
   WaitKey

[/pbcode]


     Today's little task will be to hook into the LoadFont + LoadImage commands so they can find attached resources and automatically load them for memory for you.    The frame work exists now so it should be fairly easy..  Should be.. but you never know.


 Edit #1 - Load Font Resources

      So the first step is up and running.   If you bind a CRF into the exe, the load functions will load it from the memory for you.

[pbcode]

       // This directive imports the file data into memory/exe at compile time
   #AddResource "Files/Arial36.crf"

       // The load statement check if this file is actually a resource, if so it loads it from memory
   Arial36=loadNewFont("Files/Arial36.crf",1)
   setfont Arial36
   text 200,300,"Loading directly from resource:"

[/pbcode]

      yes, it's that easy !
     


 Edit #2 - Load Image Resources (BMP/PNG/TGA)

      The second step is up and running also.   So if you bind a PNG,BMP,TGA image those images can be loaded directly from the resource buffer in memory.  They never have to be extracted to disc.

[pbcode]

       // This directive imports the file data into memory/exe at compile time
   #AddResource "Files/uwlogo.png"

       // The load statement checks if this file is actually a resource, if so, it loads it from memory
   logo=loadNewImage("Files/uwlogo.png",1)

       DrawImage Logo,200,300,true

       Sync
       waitkey

[/pbcode]
     
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on July 09, 2013, 12:16:46 AM
   PlayBASIC V1.64O  Beta 17 - Download

     Here's beta 17, this one includes the completed Resource Binding features.

     Old Beta Removed, Newer versions bellow

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on July 12, 2013, 02:11:11 AM

  PlayBASIC V1.64O - Final Documentation Pass

         Switching over to documentation mode, since can't really think of anything else worth adding.  There's already been a considerable doc's update made during this revision, so the main task now is to tack in the important new commands wrap it all up and get it out there.   It would be nice if there was actual beta testing going on that used the new abilities, but when only two people bothered to download Beta17 (bmorris & Atlus), it just makes the release build betas.

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on July 16, 2013, 01:44:47 AM
 Slowly Documenting

    Have been dropped various sessions into the doc's where possible, but haven't got that far really..   Made a bunch of updates already, but such changes are soon lost in the scope of the task.   Have added in some more examples and screen shots as they come to mind,  but there's literally 1000's of them so making screen shots for them all isn't really practical from a time perspective.  

    The plan is to release the V1.64O revision at the end of the week, so there's not that much time left for anything  major.


   
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on July 20, 2013, 06:30:13 PM
  PlayBASIC V1.64O  - ReadDir Tweaks

   While picking through the doc's found my way to the native ReadDir functions, which can be easy but the implementation isn't particularly pretty.   Which is a by-product of being one of the oldest command sets, so they tend to have a lot of legacy string thrashing in them.    If you haven't worked it out by now, string thrashing is bad news for performance.    Unfortunately this particular command is rather large containing support recursive scanning and sorting options.  Replacing it with the time I've available seems impractical, so tweaking it will have to do for the time being.    I generally don't use it, in favor of rolling my own with the FirstFile / NextFile commands.   You can find various examples of that in the source board..  

    Only had fairly quick look through the routines so far, but it seems that inside some of the scanning loops there's some redundant string operations.   These are operations that could be computed prior to entering the loop in question,  just doing that returned about 5->10% gain, but it's still way slower than doing it manually, when just scanning a simple folder at least.     Recursive scanning can be a bit of nightmare really, since the command executes in the same thread, so your program stops while the searching executes.  If you point it and large nested folder the process could take minutes.   Another reason to do it manually :)   See  GetAllFilesInDir (http://www.underwaredesign.com/forums/index.php?topic=1462.0)


Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on July 25, 2013, 08:54:33 PM
 PlayBASIC V1.64O  Beta 18  - Optimizing

    While tuning up the run time builders, noticed some chunks of code that could be better represented, by changing the input format slightly.   The idea seemed simple initially but took most of yesterday to get working again, all because of one command declaration that was in a slightly different format.. Grrr.. But it's working now.  The benefit is we remove a slab of function calls from the start up and some dead functions.    Those changes and the updated pre-processor shaved another 28K off the retail runtime.  So V1.64O is currently the same size as V164N3 (at the moment)

    The plan this afternoon is to continue testing Beta18 and pick though some of the legacy commands looking for any easy performance gains.  So far it all seems stable, but ya never know.   Tempted to add some detection operations to the compiler for finding merge friendly operations, just to see what combinations are prevalent enough to make any difference.   My suspicion is that it would be beneficial, but really depends on the type of code people use.. So one routine might benefit, where as others won't at all...


Edit#1 - Sprite Locals

    While picking though the Sprite commands and noticed  the sprites local commands have legacy string support in them.    The following test just times the average cost of writing each data type to a sprites local data.    The simple stuff like Bytes/Integers etc are about the same, but the string writing around 150 milliseconds faster..   So this code in the V164O beta 17 runs 5 FPS,  while in today's build it's 35fps..  Suspect there's a little more room in it also...  



[pbcode]

; Create a Sprite
 CreateSprite 1
 
; Attach a Local data area, 100 bytes long To this sprite
 CreateSpriteLocals 1,100


   Dim Time#(10)
   
   Max=10000


Do
   Cls

   Frames++
   Index=1
   t=timer()
      For lp =0 to Max
           SpriteLocalByte 1,0,255
      next
   Time#(Index)+=Timer()-t
   print "Sprite Local Poke Byte="+Str$(Time#(Index)/frames)
   Index++
   
   t=timer()
      For lp =0 to Max
           SpriteLocalWord 1,0,64000
      next
   Time#(Index)+=Timer()-t
   print "Sprite Local Poke Word="+Str$(Time#(Index)/frames)
   Index++


   t=timer()
      For lp =0 to Max
           SpriteLocalInt 1,0,1234567
      next
   Time#(Index)+=Timer()-t
   print "Sprite Local Poke Int="+Str$(Time#(Index)/frames)
   Index++


   t=timer()
      For lp =0 to Max
            SpriteLocalString 1,12,"Hello World"
      next
   Time#(Index)+=Timer()-t
   print "Sprite Local Poke STring="+Str$(Time#(Index)/frames)
   Index++

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

   Sync
loop

[/pbcode]


Edit#2 - Sprite Locals Peek/Poke

     Have completely ripped all the legacy string thrashing from those commands and now it takes about 2->3 milliseconds to read/write 10000 strings into a sprites local bank.   The picture bellow is from this second version of the test.. 

[pbcode]



; Create a Sprite
  CreateSprite 1
 
; Attach a Local data area, 100 bytes long To this sprite
  CreateSpriteLocals 1,100


   Dim Time#(20)
   
   Max=10000


Do
   Cls

   Frames++
   Index=1
   
   gosub Test_Poke_Functions
   gosub Test_Peek_Functions


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

   Sync
loop



;   -----------------------------------------------------------------------------
;   -----------------------------------------------------------------------------
Test_Poke_Functions:
;   -----------------------------------------------------------------------------
;   -----------------------------------------------------------------------------


   
   t=timer()
      For lp =0 to Max
           SpriteLocalByte 1,0,255
      next
   Time#(Index)+=Timer()-t
   print "Sprite Local Poke Byte="+Str$(Time#(Index)/frames)
   Index++
   
   t=timer()
      For lp =0 to Max
           SpriteLocalWord 1,4,64000
      next
   Time#(Index)+=Timer()-t
   print "Sprite Local Poke Word="+Str$(Time#(Index)/frames)
   Index++


   t=timer()
      For lp =0 to Max
           SpriteLocalInt 1,8,1234567
      next
   Time#(Index)+=Timer()-t
   print "Sprite Local Poke Int="+Str$(Time#(Index)/frames)
   Index++


   t=timer()
      For lp =0 to Max
           SpriteLocalFloat 1,12,123.456
      next
   Time#(Index)+=Timer()-t
   print "Sprite Local Poke Float="+Str$(Time#(Index)/frames)
   Index++


   t=timer()
      For lp =0 to Max
            SpriteLocalString 1,16,"Hello World"
      next
   Time#(Index)+=Timer()-t
   print "Sprite Local Poke STring="+Str$(Time#(Index)/frames)
   Index++
   
   
   print ""
   print ""
   print ""

   return
   





;   -----------------------------------------------------------------------------
;   -----------------------------------------------------------------------------
Test_Peek_Functions:
;   -----------------------------------------------------------------------------
;   -----------------------------------------------------------------------------


   
   t=timer()
      For lp =0 to Max
           Result=GetSpriteLocalByte(1,0)
      next
   Time#(Index)+=Timer()-t
   print "Sprite Local Poke Byte="+Str$(Time#(Index)/frames)
   print Result
   Index++
   
   t=timer()
      For lp =0 to Max
           Result=GetSpriteLocalWord(1,4)
      next
   Time#(Index)+=Timer()-t
   print "Sprite Local Poke Word="+Str$(Time#(Index)/frames)
   print Result
   Index++


   t=timer()
      For lp =0 to Max
           Result=GetSpriteLocalInt(1,8)
      next
   Time#(Index)+=Timer()-t
   print "Sprite Local Poke Int="+Str$(Time#(Index)/frames)
   print Result
   Index++


   t=timer()
      For lp =0 to Max
           REsult#=GetSpriteLocalFloat(1,12)
      next
   Time#(Index)+=Timer()-t
   print "Sprite Local Poke Float="+Str$(Time#(Index)/frames)
   print Result#
   Index++


   t=timer()
      For lp =0 to Max
          Result$=GetSpriteLocalString(1,16)
      next
   Time#(Index)+=Timer()-t
   print "Sprite Local Poke STring="+Str$(Time#(Index)/frames)
   print Result$
   Index++


   print ""
   print ""
   print ""


   return
   


[/pbcode]



Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on July 27, 2013, 12:04:39 AM
   PlayBASIC V1.64O  Beta 18 - Download

     beta 18 contains updated slibs and a bunch of command set (sprite + file/disc) optimizations.

       Old Beta Removed, Newer versions bellow



Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on July 29, 2013, 07:24:07 PM
 PlayBASIC V1.64O  Beta 19  - Tweaks + Tuning

       Been picking through the command set while updating the doc's and making the odd fine tune where possible.  While picking through the History noticed there's some commands like GetSpriteRect (http://www.underwaredesign.com/forums/index.php?topic=4075.0) that weren't in the docs.  This particular command was actually returning the wrong data, so it makes sense to address it there and then.      

       Spent most of yesterday looking for more 'speed up' conditions the compiler can silently make for you without much success.   The problem with such opt's is they have to operate identically, otherwise there's a risk some legacy code will break.  Have added a few more error traps to pick up when LABEL names within expressions.  Since when those things occur it'd just pop a generic Syntax Error.   They need to be a little bit more verbose..


    Here's an example.. There's more On the subject Here (http://www.underwaredesign.com/forums/index.php?topic=4076.msg27514#msg27514)


[pbcode]

   ; Attempt to create a variable called WOMBAT, will fail
   ; since WOMBAT key is already defined as LABEL
 
       Wombat = 45

     end
   
   
   ; define subroutine called WOMBAT starting point

Wombat:
    print "This is the Wombat sub-routine"
  return    


[/pbcode]
   
   This is pop's an error on the Wombat = 45 line ,telling us the that Wombat is previously been defined as a label.




EDIT #1 - Popping error between operators and labels

   
[pbcode]

   ; operations between labels are illegal, but it'll pop an error
   ; that WOMBAT is a label
 
 
     ; This would error
      a = Wombat * 100
 
      ; This would error
      a = 100* Wombat
      

      
     end
   
   
   ; define subroutine called WOMBAT starting point

Wombat:
    print "This is the Wombat sub-routine"
  return    

[/pbcode]

   It's still possible to sneak one through that, since the expression resolver tends to per-compute stuff out as literals,    eg...   Restore Wombat  



EDIT #2

        Added more traps on label names in structural statements.  Should catch a fair degree of those..  While looking at errors, have customized the command input parameter error statement, so it gives the parameter index  in the error message as well what data type it's expecting.       

eg   
   PositionSprite 1,x

Would spit out

       'PositionSprite' commands parameter #3 is incorrect, expecting 'Integer / Float' Data type


      Another one that you're probably hit upon at some point is a Expecting Equals error.   Theres a number of situations  where the pattern matching is expecting some user variable be followed by an equals token. But you'd even get this generic error when you forget to add some expression..   


eg.

      MyVariable

  Now spits out something along the lines of

     Expecting equals in assignment Eg. 'MyVariable = Expression'

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on July 31, 2013, 01:58:13 AM
  PlayBASIC V1.64O  Beta 19  - Prototype Pass #1 Tweaks

      This is a bit of an oldie but a goodie that's a by-product of the skimming nature of the Pass#1 in the compiler.   During Pass#1 the compiler is only looking for Labels and function headers.  These are needed up front so we can work out what input / return parameters things like functions will have before building code. This is what allows  a function or label call to be used before the compiler has actually got to that chunk of code.    Otherwise you wouldn't be able to, you'd have to provide a list of prototypes.  Which can be rather tedious..  

      Eg,
[pbcode]
     ; call our function
     HelloWorld(100,200)

    ; the function code
Function HelloWorld(Xpos,Ypos)
   print Xpos,Ypos,"Hello World"
EndFunction

[/pbcode]

     Since the compiler works top to bottom, when it finds the HelloWorld keyword during pass #2, it searches the Function name stack (built during pass#1) for the parameter pattern to match the expression with.    if we didn't do this, we'd need to previously provide a prototype for every function call.  

     The problem with Pass#1 is that it's a dumb skim over the input code at text level.  So it didn't really look at the lines of code, it just searched for the function/sub headers.  All of the real parsing occurs  during pass#2 in the compiler, since everything is tokenized on demand during pass #2.    This creates a catch 22 with things like remarks blocks.   Since the pass#2 was the only remark aware pass, if you wrapped a remark pair around a function say, then the remarks won't have any effect.    Pass #1 would see the function header/footers,  so the function prototype would still exist.  Creating a bit of a WTF moment.

     This afternoon i've been updating the Pass#1 to at least skim for remark blocks.   So far it only supports the /*  to */ remark  blocks, but RemStart to RemEnd


     This example would parse differently in today's build than older versions.   Today's build skips the function block completely, so when you try and compile this code,  TEST() is now undeclared and PB doesn't know what it do with it,  so it errors..

[pbcode]

 /*  Multi Line COmment on single line */  print "Some Text"

 test(10)

 Print "Some more text to fill space  "
 
   /*

Function TEst(YEah)


EndFunction
  */
 

 Sync
 waitkey
 

[/pbcode]


 #If / #EndIF Directives Limitations

       Unfortunately, If you wrap an #IF / #ENDIF around a function /psub in the code and try to toggle this OFF / ON in the code, then this won't work for the same basic reason.    #IF statements and Constants etc only exist during PASS#2,  the Test() function will be picked up during prototyped in PASS#1, but that slab of code gets skipped during pass two.   This creates a situation where PB can't resolve the address to the TEst() function cal.  So you'd get an strange error along those lines.


[pbcode]

  Constant  Include_This_Function = NO

 test(10)

 

  #if Include_This_Function=yes

   ; Pass #1 will see this function regardless of the directive,
   ; since those are only processed during pass #2

Function TEst(YEah)


EndFunction

  #endif
 
 

 Sync
 waitkey
 


[/pbcode]  




  Edit #1:  RemStart / RemEnd Supported

[pbcode]
 test(10)
 
   remstart    
Function TEst(YEah)


EndFunction
   remend
     

 Sync
 waitkey
 
[/pbcode]




Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on July 31, 2013, 06:21:22 PM
   PlayBASIC V1.64O  Beta 19 - Download

     beta 19 includes the updated pre-pass in the compiler and a bunch of error trapping tweaks that should make like easier.

      Old Beta Removed, Newer versions bellow

Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: ATLUS on August 01, 2013, 07:26:12 AM
remstart and remend is this old function?
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on August 01, 2013, 07:08:05 PM
Quote from: ATLUS on August 01, 2013, 07:26:12 AM
remstart and remend is this old function?

Yep, they're as old as PB (http://www.underwaredesign.com/forums/index.php?topic=442.0)


Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on August 02, 2013, 12:05:05 AM
 Threaded Queued Blits maybe ?

     Since the V1.64N2 revisions we've had threading support for the blit image functions.   This allows the entire blit operation to be pushed off the programs core and unto a second core.   Giving us the ability to write asynchronous rendering routines.  The only limitation is that there's no queue support.  

     Today's little task has been to drop in a way to queue up a series of blits, then perform them all on the second CPU core.. Internally there's a stack of potentially 64 operations.   Which might not sound like much but that's way more than we actually need, considering we're talking about calling functions that are for performing screen sized operations.    Under the current implementation,  the user simply turns on the queue threading mode  via BlitFXThreadIngMode 2 (Start Queue) then calls the blitimage commands they want.    These calls don't render anything, they store the call information on the thread stack.   When we're done preparing our To DO list, we set the  BlitFXThreadIngMode 3 this then launches the render thread.   At least that's the theory,  since it sure doesn't want to work yet..


Edit #1

        Ok, so it's couple hours later and i've finally found the problem with the queue and now it seems to be working, at least on my test machines.   Not too keen on the command names though, so will probably rename them as BlitImage  commands, since they're part of that family.

        The queue is executes in the order they'd saved.  So if you called BlitImageAlphaPostMultColour  when the queue is enabled, it'd stack like this,

[pbcode]
    ; call #0
        BlitImageAlphaPostMultColour(Screens(FrontBuffer),0,0,$e0a090)
    ; call #1
        BlitImageAlphaPostMultColour(Screens(FrontBuffer),0,0,$e0a090)
    ; call #2
        BlitImageAlphaPostMultColour(Screens(FrontBuffer),0,0,$e0a090)
    ; call #3
   BlitImageAlphaPostMultColour(Screens(FrontBuffer),0,0,$e0a090)
    ; call #4
        BlitImageAlphaPostMultColour(Screens(FrontBuffer),0,0,$e0a090)
[/pbcode]
 

     So obviously when the thread executes, it'll no call #0, #1, #2, #3 , #4 in that order.   This allows you to set up a list of brute operations and run them externally to our logic.   This is really the whole idea of multiple CPU CORES,  it allows us divide and conquer.   The potentially this that threading can make your program twice as fast, that's assuming a best case scenario where the load can be balanced perfectly, which is just fantasy.  The reality is that you're program is bound to have an uneven load. 

     For example.  if we push off 5 milliseconds worth of rendering onto core #2, but core #1 only has 1 milliseconds worth of work to do before it needs to use the images core #2 is working on.  Then Core #1 ends up sitting around waiting for that task to complete, and we're losing most of the benefit.    The goal should be to lay out our program so we can interleave the two task together in such a way that they either take the same time or core #2 completes it's task long before we need the result. 

     Threading introduces a few no no's, the most immediate important one  would be ownership of image resources.   if you set up a render task and start the thread (run it on core#2), then the images that thread is using are now as no got zone for you're core#1, until the thread has completed it task.    This is because the two CPU's are potentially writing to the same memory at the same time.   This is not possible in single cpu (core) system, where you can get away with this type of logic, but it's won't work on multi core systems.    You can render to the same image, you just have to  make you're not drawing over, or reading from drawn over shared pixels. If you do, you'll wacky unpredictable results.. 
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on August 02, 2013, 11:28:51 PM
PlayBASIC V1.64O BETA #20 (Retail Compiler Only Beta) - (Avail for Registered Users ONLY)  (3rd,July,2013)

     PlayBASIC V1.64O  Beta #20 sees the addition of the Thread Queue mode in the blitimage library as well as some changes to those functions names.    

     The blitimage commands are by design big job commands, meaning they do a lot of data processing, making them ideal for threading.   Threading for those who many not know, is executing a 'function' on a different CPU core.   So when we thread a blitimage function, PlayBASIC passes this task from our program onto some other cpu.   In systems that have more than one cpu core, or physical cpu we're thus executing two things at once.   Systems with a single core cpu can still use threading, but the  jobs are executed by the system in a 'one at a time' fashion.   Depending upon the size of the threaded job, this can still be of benefit to a single core system..

     This build of PlayBASIC supports two different types of threading.   We have an immediate single job mode an a queue mode.  We control these using the  BlitIMageThreadMode MODE  command

      Mode states

      0 =  Threading OFF, All blitimage calls are drawn by the programs core immediately
   
      1 =  Push Single Job,  When this mode is enabled, the next blitimage function called will push this task onto a second core and execute it now.  

      2 =  Start Queue.   This setting makes the  blitimage function calls stack up.    They're not executed until you set the Mode to Render QUEUE mode

      3 =  Render Queue.   Fires up a thread that renders the captured list of rendering tasks.  



      Commands

   WaitOnBlitImageThread()    - Waits for a previously started thread to complete it's work.  This is very important when threading, since we don't really know how long the system is going to take to execute our threaded task.  So when we need to use the images the threads are drawing onto/with we need to wait for it.  Other wise you risk the two cores writing to the same data.  Which is BAD :)


   BlitImageThreadMode Mode       - Set threading mode

   mode=GetBlitImageThreadMode()    - Get the current threading mode

   BlitImageThreadPriority(PriorityValue)   - Threads can have a priority (1 to 15), generally the higher the value the more 'important the system should take this request.  


   PriorityValue=GetBlitImageThreadPriority()    - Read the priority value

   State=GetBlitImageThreadStatus()   - Check if Threading is active or not ?   0 = Thread is no longer running.  1 = Running.  


   WaitOnBlitImageThread()         - Wait and clean up threads if need be.  



   SizeOfStack=GetBlitImageThreadQueueSize()           - Check the size (number of blitimage requests) on the blit queue.


     






Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: ATLUS on August 03, 2013, 08:13:06 AM
I run some example(PB1.64L) codes and my codes, work fine.
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on August 05, 2013, 01:13:58 AM
Quote from: ATLUS on August 03, 2013, 08:13:06 AM
I run some example(PB1.64L) codes and my codes, work fine.

  Well that's good to know.   Have you tried seeing what you can do with new commands though ????


Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on August 05, 2013, 01:29:30 AM
   PlayBASIC V1.64O  Beta 21 - Threaded Light Map

     Writing some examples for the threading support in blit image library,  which is not the easiest, but slowly getting somewhere.   Mostly been using other blit image examples such as the light map example as basis of the examples.   To draw a light map we need two images, the opaque version (unlit original image) and the light map image.  These two images are multiplied together and output as the final lit image.  

     Now we've queued threading mode, we can batch some of the work up and push it off onto a second thread.  In this example we're pushing the merge and clear process onto the queue.   When we start this drawing, we start drawing the alternative light map into the second fx image buffer.  Otherwise we'd have to sit and wait, which would make threading those tasks useless.  Wrapping your heads around this is fundamental to being able to use threading successfully.  The more work you can push off and into a single queue the better also.


    PlayBASIC V1.64O Beta 21 version (higher)

[pbcode]


   ; Inlude the Blit Image functions
   #include "BlitImage"
   

   ; Create an FX image the size of the screen
   Dim LightMap(2)
   LIghtMap(0)         =NewImage(GetScreenWidth(),GetScreenHeight(),2)
   LIghtMap(1)         =NewImage(GetScreenWidth(),GetScreenHeight(),2)


   FrontImage   =0
   BackImage   =1-FrontImage
   

   ; Create a second  FX image the size of the screen
   ; we'll be using to blend with our other image
   Backdrop=NewfxImage(GetScreenWidth(),GetScreenHeight())

   ; fill the backdrop with something so we can see it
   size=64
   Tile=NewImage(size,size,2)
   RendertoImage Tile
   cls $445566
   boxc 0,0,size-1,size-1,false, $111111
   
   rendertoIMage Backdrop
   TileIMage Tile,0,0,false


   LightCol=$f08040

   
   Do

      ; Set threading mode to capture.
      ; this allows us to capture the next two blit image functions to
      ; the interal 'to do' list, so both jobs can be done on the seperate thread.

         BlitImageThreadMode 2

         ; redirect all drawing to screen back buffer   
         rendertoscreen

            ThisLIghtMap=LightMap(FrontImage)

            ; To do combined Blit (copy) our Image.  This
            ; version multiples the pixels in the blend
            ; image (MyImage) with the backdrop. So it's
            ; using the blend image as light map.
            BlitImageAlphaMultImage(BackDrop,0,0,ThisLightMap)   
   

            rendertoimage ThisLightMap
            BlitImageClear(ThisLightMap,0,0,rgb(00,00,00))   


         BlitImageThreadMode 3


         rendertoscreen
      

      ; redirect all drawing to this image
      RenderToimage LightMap(BackImage)

      if LeftMouseButton()<>0 then LightCol=RndRGB()

      ; draw a circle at the mouses current position   

       Draw_Light(100,100,150,$445566)

       Draw_Light(MouseX(),Mousey(),250,LightCol)
      

       Draw_Light(300,200,150,$ff00000)

       Draw_Light(700,400,150,$445566)



      rendertoscreen

      setcursor 0,0

      ; make pb wait until our thread queue is done before drawing to the screen.      
      WaitOnBlitIMageThread()

      ; Display Message
      Text 0,0,"Threaded Queue Example "
      Text 0,20,"Left Mouse to change light colour"
      text 0,40,Fps()

      ; slip the light map buffers   
      FrontImage   =1-FrontIMage
      BackImage   =1-BackImage

   
      ; flip the back buffer to the front, so the user can see it
      Sync
      
   loop



Function Draw_Light(X#,y#,Radius,Colour=$ffffff)  

      Colour2=Rgbfade(Colour,5)

      Edges=16
      steps#=360.0/Edges
      inkmode 1+64
      For lp=0 to Edges-1
         Angle1#=lp*Steps#
         Angle2#=wrapangle(Angle1#,Steps#)
      
         x1#=x#+cosradius(angle1#,Radius)
         y1#=y#+sinradius(angle1#,Radius)
      
         x2#=X#+cosradius(angle2#,Radius)
         y2#=y#+sinradius(angle2#,Radius)

         GouraudTri x1#,y1#,Colour2,x2#,y2#,Colour2,x#,y#,Colour

      next
      inkmode 1

EndFunction


[/pbcode]


    This example requires V1.64O to function as intended,  since the BlitImageClear command isn't able to read/write to the same buffer due to a  logical error.  


    PlayBASIC V1.64O Beta 20 version

[pbcode]


   ; Inlude the Blit Image functions
   #include "BlitImage"
   

   ; Create an FX image the size of the screen
   Dim LightMap(2)
   LIghtMap(0)         =NewImage(GetScreenWidth(),GetScreenHeight(),2)
   LIghtMap(1)         =NewImage(GetScreenWidth(),GetScreenHeight(),2)


   FrontImage   =0
   BackImage   =1-FrontImage
   

   ; Create a second  FX image the size of the screen
   ; we'll be using to blend with our other image
   Backdrop=NewfxImage(GetScreenWidth(),GetScreenHeight())

   ; fill the backdrop with something so we can see it
   size=64
   Tile=NewImage(size,size,2)
   RendertoImage Tile
   cls $445566
   boxc 0,0,size-1,size-1,false, $111111
   
   rendertoIMage Backdrop
   TileIMage Tile,0,0,false


   LightCol=$f08040

   
   Do

      ; Set threading mode to capture.
      ; this allows us to capture the next two blit image functions to
      ; the interal 'to do' list, so both jobs can be done on the seperate thread.

         BlitImageThreadMode 2

         ; redirect all drawing to screen back buffer   
         rendertoscreen

            ThisLIghtMap=LightMap(FrontImage)

            ; To do combined Blit (copy) our Image.  This
            ; version multiples the pixels in the blend
            ; image (MyImage) with the backdrop. So it's
            ; using the blend image as light map.
            BlitImageAlphaMultImage(BackDrop,0,0,ThisLightMap)   
   

            rendertoimage ThisLightMap
;;;            BlitImageClear(ThisLightMap,0,0,rgb(00,00,00))   
            BlitImageAlphaSubColour(ThisLightMap,0,0,rgb(255,255,255))   


         BlitImageThreadMode 3


         rendertoscreen
      

      ; redirect all drawing to this image
      RenderToimage LightMap(BackImage)

      if LeftMouseButton()<>0 then LightCol=RndRGB()

      ; draw a circle at the mouses current position   

       Draw_Light(100,100,150,$445566)

       Draw_Light(MouseX(),Mousey(),250,LightCol)
      

       Draw_Light(300,200,150,$ff00000)

       Draw_Light(700,400,150,$445566)



      rendertoscreen

      setcursor 0,0

      ; make pb wait until our thread queue is done before drawing to the screen.      
      WaitOnBlitIMageThread()

      ; Display Message
      Text 0,0,"Threaded Queue Example "
      Text 0,20,"Left Mouse to change light colour"
      text 0,40,Fps()

      ; slip the light map buffers   
      FrontImage   =1-FrontIMage
      BackImage   =1-BackImage

   
      ; flip the back buffer to the front, so the user can see it
      Sync
      
   loop



Function Draw_Light(X#,y#,Radius,Colour=$ffffff)  

      Colour2=Rgbfade(Colour,5)

      Edges=16
      steps#=360.0/Edges
      inkmode 1+64
      For lp=0 to Edges-1
         Angle1#=lp*Steps#
         Angle2#=wrapangle(Angle1#,Steps#)
      
         x1#=x#+cosradius(angle1#,Radius)
         y1#=y#+sinradius(angle1#,Radius)
      
         x2#=X#+cosradius(angle2#,Radius)
         y2#=y#+sinradius(angle2#,Radius)

         GouraudTri x1#,y1#,Colour2,x2#,y2#,Colour2,x#,y#,Colour

      next
      inkmode 1

EndFunction


[/pbcode]




Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: ATLUS on August 06, 2013, 01:29:02 PM
I've tested compatibility =]
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on August 06, 2013, 10:04:28 PM

  1300 club

     Today the PlayBASIC documentation reached a staggering 1300 pages.   




Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on August 08, 2013, 08:14:24 AM
   Sticking a fork in it

       At the end of tonight It's looking like we're ticked all the boxes for this update and a few more for good measure.   Only had a small amount of the PB time today, but manged to run through another cross reference session on the documentation.      So the only thing left to do now is build the next updater, but that's something for tomorrow.   Hopefully the V1.64O final should be up on the server in a day or so.  


Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: monkeybot on August 08, 2013, 12:05:48 PM
nice!
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on August 09, 2013, 10:31:40 AM

   PlayBASIC V1.64O  Retail Upgrade

      Yep.. finally the  PlayBASIC V1.64O retail update has been built, stuck together and slapped online...  Have fun..

      Download PlayBASIC V1.64O Retail Upgrade (http://www.underwaredesign.com/forums/index.php?topic=1182.msg27547#msg27547)  (9th,Aug,2013)


Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: ATLUS on August 09, 2013, 10:35:10 AM
Very nice!
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: Sigtrygg on August 09, 2013, 03:57:05 PM
My programs work fine!

Thank you!  :)
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: kevin on August 09, 2013, 10:15:03 PM

Thanks, but it's a bit late now to start testing, you're meant to be testing during the beta  period not after.  It's too late now to make any such corrections.
Title: Re: PlayBASIC V1.64O (Work In Progress) Gallery
Post by: Sigtrygg on August 10, 2013, 03:11:01 AM
Yes, of course you are right. I haven't got enough time for PlayBasic during the last months, because I learnt some about C and RobotC and I took part on a robot virtual world competition.
PlayBasic is the most comfortable programming language for me and I have most of fun with it! I very appriciate your work!

Bye,

Sigtrygg