News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

PlayBasic V1.64M (Work In Progress) Gallery

Started by kevin, May 25, 2010, 01:37:57 AM

Previous topic - Next topic

kevin





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


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


    For OLDER upgrade work in processes see,

    See  PlayBASIC V1.64L Learning Edition History (Building learning Edition Thread)

    See  PlayBASIC V1.64L


    For NEWER upgrade work in processes see,

     See  PlayBASIC V1.64P (login required)   -     Convert PlayBASIC To Machine Code Dll's

    See  PlayBASIC V1.64O

    See  PlayBASIC V1.64N2 / V1.64N3

    See  PlayBASIC V1.64N






PlayBasic V1.64M  Beta 1


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

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

      To add your ideas see ->  User base survey of optional parameter additions for PlayBASIC V1.64M  (Don't post them here!)


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

       Example,
PlayBASIC Code: [Select]
   screen=newfximage(800,600)

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

Do

rendertoimage screen
c1=255
c2=rgb(100,40,100)
shadebox 0,0,800,600,c1,c1,c2,c2

setcursor 0,0
alpha=128+cosradius(angle#,127)
angle#=wrapangle(angle#,2)
ink argb(alpha,255,0,0)
lockbuffer
setfont 2
Print PlayBasic$

print "BuildTime:"+STR$(t)+" Ticks"
print "FontType:"+STR$(getFontType(2))
print "FPS:"+STR$(fps())
unlockbuffer

rendertoscreen
drawimage screen,0,0,false

Sync
loop



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


kevin

#1
 PlayBasic V1.64M  Beta 2 - Convert Bitmap Fonts to CRF format

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

PlayBASIC Code: [Select]
   screen=newfximage(800,600)
;screen=0

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


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

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

; NullPixel =point(0,0)

Do

rendertoimage screen
c1=55
c2=rgb(100,80,50)
shadebox 0,0,800,600,c1,c1,c2,c2

setcursor 0,0
alpha=128+cosradius(angle#,127)
angle#=wrapangle(angle#,2)
ink argb(alpha,255,0,0)

setfont 2
lockbuffer
Print PlayBasic$

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

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

Sync
loop





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

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


PlayBASIC Code: [Select]
   Screen=NewFXImage(800,600)
; Include the FONT Extras library
#Include "fonts"

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


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

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


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


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


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

if GetFontStatus(5)
SetFont 5
ink $80ff00ff
CenterText cx,150,"...this is an ok custom bitmap font..."
CenterText cx,200,"..custom bitmap font..."
endif

if GetFontStatus(10)
SetFont 10
CenterText cx,300,"...but this one is..."
CenterText cx,350,"...much nicer!!!..."
endif

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








kevin

#2
  PlayBasic V1.64M  Beta 2b - Creating CRF Fonts Internally

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

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

     So,

      CreateBitmapFont FontIndex,FontIndex,MaxChrWIdth,MaxChrHeight,4

      is the same as

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

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

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


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

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

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

starttime=timer()

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

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

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

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

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

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

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

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

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

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

Sync
Waitkey



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

Sync
loop




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




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

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

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

PlayBASIC Code: [Select]
   Logo=LoadNewAFXImage(Path$+"PlayBasicSig.png")

Width=400
Height=400

CreateBitmapfont 2,Width,Height,8

IMage=NewImage(width,height,8)

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

fontdrawmode 2,1


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

shadebox 0,0,800,600,c1,c1,c2,c2

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

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

if Upkey()
logocount+=1
endif

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

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

Sync
loop







kevin

#3
  PlayBasic V1.64M  Beta 4 - Final Touches On Fonts

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

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

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

PlayBASIC Code: [Select]
   loadFont "arial",1,48,0

Cls 255

Screen=Newimage(800,600,2)

rendertoimage Screen

print "hello world"

ink $ffff0000
print "This is text drawn using a local CRF"

rendertoscreen

drawimage Screen,100,10,false

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






 Rendering Video Bitmap Font to FX surface

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

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

PlayBASIC Code: [Select]
   LoadFont "Arial",1,32,0

print "Windows Font"
print "Type:"+STR$(getFontTYpe(1))

MakeBitmapFont 1,$ff00ff
print "Video Bitmap Font"
print "Type:"+STR$(getFontTYpe(1))

Width =getFontWidth(1)
Height=getFontHeight(1)

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

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

rendertoimage 0

drawimage Screen,300,0,false

Sync
waitkey





kevin

#4
  PlayBasic V1.64M  Beta 4/5- Better Support For Mismatched Surface Types

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

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


 SaveFont Example

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


PlayBASIC Code: [Select]
   path$=" THE LOCATION OF THE FRECH.PNG file on your computer"

; Include the FONT Extras library
#Include "fonts"

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

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

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

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

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

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

; show the message to the user
Sync
waitkey





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

 

kevin

#5
  PlayBasic V1.64M  Beta 5- Dynamic Font Quantity Controls

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


PlayBASIC Code: [Select]
   t=timer()
FontQuantity 7

For lp=2 to GetFontQuantity()
LoadFont "Arial",lp,32+(lp*4),0
Select Rnd(4)
case 1
Makebitmapfont lp,$00ff00,2

case 2
Makebitmapfont lp,$ff0000,4

case 3
Makebitmapfont lp,rndrgb(),8
endselect
setfont lp
print "Testing"
next
t=timer()-t
print "done"
print t
sync
waitkey
waitnokey


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

next
setfont 1

print "done"

Sync
waitkey


   

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

      eg..

PlayBASIC Code: [Select]
    ; remove the default font
DeleteFont 1

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

; Refresh screen
Sync
WaitKey





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




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

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

PlayBASIC Code: [Select]
   * Font Command Set Changes

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

; The bitmap format parameter lets you load and convert the
; loaded font in one command.

- Fontindex=LoadnewFont(Filename$, [Size=0], [Style=0], [BitmapFont=1] )



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



- SaveFont Filename$, [FontIndex]

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


- FontQuantity NumberOfFonts - Expands or shrink the fonts table



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

- GetFreeFont()

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

- LoadNewFont() also includes autofont quantity management.



- MakeBitmapFont ThisIndex, Colour, [Format=2]

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


- MakeBitmapFont support various conversion methods such as,

* Windows GDI fonts To Video Bitmap (MakeBitmapFont ThisFont,Colour,2)
* Windows GDI fonts To FX Bitmap (MakeBitmapFont ThisFont,Colour,4)
* Windows GDI fonts To Compressed Raster (MakeBitmapFont ThisFont,Colour,8)
* Bitmap fonts To FX BITMAP (MakeBitmapFont ThisFont,Colour,4)
* Bitmap Fonts To Compressed Raster (MakeBitmapFont ThisFont,Colour,8)
* FX Bitmap fonts To BITMAP (MakeBitmapFont ThisFont,Colour,2)
* FX Bitmap Fonts To Compressed Raster (MakeBitmapFont ThisFont,Colour,8)









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

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

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


- GetFontChr has improved Bitmap font support.

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






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

PlayBASIC Code: [Select]
   Font=LoadNewFont("Verdana",48,1,8) ; load it as bold and convert it to crf
SetFont Font
print "Hello World"

Sync
waitkey







kevin

#6
  PlayBasic V1.64M  Beta 6 - Compile Time Improvements

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

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


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

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


  Print  Cos(45)


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

   
  Some ugly test code ,    
   
 
PlayBASIC Code: [Select]
   // Compile Time Replace functions
constant Replace_TEST1$ =replace$("Hello Bill","Bill","World",1,false,false)
constant Replace_TEST2$ =replace$("Hello Bill",autocaps$("BILL"),"World",1,true,false)
constant Replace_TEST3$ =replace$("Bill BILL bill bIll",autocaps$("BILL"),"Dude",1,true,false)

print Replace_TEST1$
print Replace_TEST2$
print Replace_TEST3$

Show()


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

print Instring_TEST1
print Instring_TEST2
print Instring_TEST3

Show()


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


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

Show()


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

print BIN_TEST$
print Hex_TEST$

Show()

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

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


print iVal_Test1
print iVal_Test2

print fVal_Test1#
print fVal_Test2#

Show()



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

print CutL_Test1$
print CutR_Test1$

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

Show()



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

print PadTest1$

Show()


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

print StrTest1$
print StrTest2$

Show()



// Compile Time ASC() pre-solve

print StrTest1$
print StrTest2$

Show()

Function Show()

Sync
WaitKEY
waitnokey
cls
endfunction






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


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


PlayBASIC Code: [Select]
   constant Date$=autocaps$("01 AUG 2010")

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

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

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

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

print TodaysDate$
sync
waitkey






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

 Print "1st,Aug,2010"
 sync
 waitkey


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

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


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

 
PlayBASIC Code: [Select]
   #if PBCompileMode=0
print "Running from the editor"
print "put my debug code into the game"

#else
print "Code in the final game"
#endif





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

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

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


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

      print "Code in the final game"


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




   So

     
 

kevin

#7
  PlayBasic V1.64M  Beta 7 - Download Available

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


 Download

   Deleted - Newer Beta's bellow.




kevin

#8
  PlayBasic V1.64M  Beta 8 - Suspended

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

    READ ARTICLE (login required)

kevin

#9
  PlayBasic V1.64M  Beta 8 - Continues

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

  READ ARTICLE (login required)

kevin

#10
  PlayBasic V1.64M  Beta 9 - Download Available

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


 Download

    Deleted -> Newer Version bellow



kevin

#11
 PlayBasic V1.64M  Beta 10 - Download Available

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


 Download

   Deleted, Newer version bellow.


kevin

#12
  PlayBasic V1.64M  Beta 11 - Compile Time Pre-Solver Improvements (Cont)

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


PlayBASIC Code: [Select]
   constant RGBAND_TEST1=RGBAlphaAND($ffffffff   ,argb($f,$f0,$7f,$07))
constant RGBOR_TEST1 =RGBAlphaOR($f1f1f1f1 ,argb($8,$8,$8,$8))
constant RGBXOR_TEST1=RGBAlphaXOR($cccccccc ,argb($ff,$ff,$ff,$ff))

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

show()


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

print "RGBADD FUNCTION"
print Hex$(RGBADD_TEST1)

print "RGBSUB FUNCTION"
print Hex$(RGBSUB_TEST1)

print "RGBMULT FUNCTION"
print Hex$(RGBMULT_TEST1)

Show()


constant RGB_TEST0=rgb($ff,0,0)
constant RGB_TEST1=rgb(255,0,0)
constant RGB_TEST2=rgb(0,255,0)
constant RGB_TEST3=rgb(0,0,255)

print "RGB FUNCTION"
Print Hex$(RGB_TEst0)
Print Hex$(RGB_TEst1)
Print Hex$(RGB_TEst2)
Print Hex$(RGB_TEst3)


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

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


show()







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

Print Bin_String$
Print Hex_String$
print ASC_VALUE
print CHR_STRING$
print Flip_String$
Show()


Function Show()

Sync
WaitKEY
waitnokey
cls
endfunction





 

 Continued Pre-Solver Improvements...

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

PlayBASIC Code: [Select]
   Constant Dinstance2d_test#=GetDistance2d(100,200,400,500)
Constant Dinstance3d_test#=GetDistance3d(100,200,400,500,600,700)
print Dinstance2d_test#
print Dinstance3d_test#
a=100
print GetDistance2d(a,200,400,500)
print GetDistance3d(a,200,400,500,600,700)
show()


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

print Mod_Test1
print Mod_Test2
print Mod_Test3
print Mod_Test4

show()

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

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


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

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

show()



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

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

show()

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




show()


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


a#=123.78

Constant Int_test1 = 123.78
Constant Int_test2 = Int(123.78)

Print INt_test1
Print INt_test2

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

Print Float_test1#
Print Float_test2#

show()



a#=100.45

Constant TestAngle# =100.45

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

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

print Root_Test1#
print sqrt(A#)

print Cos_Test#
print Sin_Test#
print Tan_Test#

print aCos_Test#
print aSin_Test#
print aTan_Test#


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

show()




  Now onto something a little more interesting..



 PlayBasic V1.64M  Beta 11 Download

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




kevin

#13
  PlayBASIC V1.64M  Beta #12 - Mapping Or Sprites Next ?

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

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

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

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

    What fun...



 Stevmjon's Platformer Being Used For Map Testing

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

    As for how it works,  head over to the  stev's thread

     
             

kevin

#14
  PlayBASIC V1.64M  Beta #12 - Mapping Updates

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

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

PlayBASIC Code: [Select]
 screen=newimage(800,800)
rendertoimage screen
cls 255
circle 400,400,400,true


BlockWidth=100
BlockHeight=100

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

Level=NewLevel(Map,8,8)


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

rendertoscreen
cls $00ff00
drawmap map,Level,0,0
print "Video map"
Sync
waitkey





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

PlayBASIC Code: [Select]
 screen=newfximage(800,800)
rendertoimage screen
cls 255
circle 400,400,400,true

BlockWidth=100
BlockHeight=100

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

Level=NewLevel(Map,8,8)


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

rendertoscreen
cls $00ff00
drawmap map,Level,0,0
print "FX map"
Sync
waitkey