Orientation guide for existing Blitz users

BlitzMax Forums/BlitzMax Beginners Area/Orientation guide for existing Blitz users

(Updated 5 Jan 2005.)

Here are some key changes you should be aware of from previous versions of Blitz.

Graphics
Graphics now has different parameters: width, height, depth and refresh rate.

If you're trying to port an existing program that uses the last 'window mode' parameter, you'll probably find that your game runs at a crawl. This is because BlitzMax defaults to locking game update speed to that of the display refresh rate. If you've passed 1, 2 or 3 as the last parameter of Graphics, your game will be updating at 1, 2 or 3 Hz respectively! Just delete the last parameter.

Images
Because BlitzMax's 2D engine (Max2D) now renders images using OpenGL (allowing drawing to be accelerated using 3D hardware), you can now carry out operations such as scaling, rotation and alpha blending of images (ie. making them see-through) in real time.

Unlike previous Blitzes, you don't set the rotation, scale or alpha level of individual images, but instead call SetRotation, SetScale and SetAlpha, which will affect all drawing operations until you call them again with different values.

This means that if you call SetScale 0.5, 0.5, all images will be drawn at half their normal width and height until you revert back to normal scaling with SetScale 1, 1, and may mean calling these commands before drawing individual images if they are to be drawn with different values. This is how OpenGL works internally, so is very fast.

Images are also affected by SetColor, allowing images to be 'tinted'. The red, green and blue values in an image are affected by the percentage of red, green and blue values you specify with SetColor, so 255, 255, 255 gives 100% for each of the red, green and blue values in an image, meaning it will be drawn normally; SetColor 127, 127, 127 would give (approximately) 50% of each value, effectively making the image half as bright, SetColor 0, 255, 255 would take away all of the red component in an image, and SetColor 255, 0, 0 would leave only the red component, effectively tinting the image red.

If you've called SetColor with anything other than 255, 255, 255, and then want to draw your images normally, call SetColor 255, 255, 255 before doing so. You'll probably notice you need this when your images start to flash unexpectedly in different colours!

KeyDown/KeyHit
BlitzMax now features a set of pre-defined keycode constants with different numerical values to previous Blitzes. See the Key Codes section of the documentation (under Module Reference) for details. In particular, if you use the common "Repeat [... ] Until KeyHit (1)" to detect the Esc key, change it to KeyHit (KEY_ESCAPE). The value 1 now relates to a left mouse button press, so don't wear out your Esc key in confusion and frustration...

Lists
Blitz 'type' objects were previously added automatically to a single list per type. This is no longer the case. Because BlitzMax allows multiple lists per type, you must create the list manually. Fortunately, this is as easy as:
mylist:TList = CreateList ()

Note that the list variable mylist is created as type TList, an internal BlitzMax type. You add objects to this list using the ListAddLast command (the example below assumes a type called 'Example' has been created):
myobject:Example = New Example
ListAddLast mylist, myobject

Instead of iterating through lists using the For... Each construct, use the new For... EachIn construct:
For e:Example = EachIn mylist
    Print e.blah
Next


Syntax
Variable types are now declared using the : symbol, not the . symbol:

' Old version:
p.Player = New Player

' New version:
p:Player = New Player


Type field access now uses the . character instead of the \ character:
Type Oink
	Field x
End Type

o:Oink = New Oink
o.x = 1

Print o.x


The core variable types use the same shortcut symbols as before (only available for the most common types), with the addition of ! for double-precision (64-bit) floating point variables; you can also use their names if you prefer:
' Integers:

i = 5 ' First reference to a variable assumes integer if nothing specified...
i% = 5
i:Int = 5

' Floats:

f# = 5.0 ' (Tip for UK Mac users: The # character is obtained via Alt + 3!)
f:Float = 5.0

' Strings:

s$ = "Oink"
s:String = "Oink"

' Bytes:

b:Byte = 1

' Shorts:

s:Short = 10

' Doubles:

d! = 10000
d:Double = 10000


Labels
Labels are now defined using the # character:

#mylabel
If a = 1 Then Goto mylabel


Data
Data sections are now accessed via DefData, RestoreData and ReadData. Note the use of the new label syntax again:
RestoreData mydata

For a = 1 To 5
	ReadData info
	Print info
Next

#mydata
DefData 2, 4, 6, 8, 10


Feel free to post your own discoveries, and try not to get too upset about the changes. You may well trip up for a while, but you'll soon get the hang of it!

5 Jan 2005: Added stuff about images, more FlushMem stuff and been clearing up thread a bit (still working on adding stuff here).

(NB. I'm going to delete suggestions once I've added/discarded them here, to try and keep it tidy-ish!)

i dunno if by suggestions you mean actual typed up, helpful examples or wildly flailing "help i can't find..." questions, so here goes

help, i can't find...

commandline
apptitle
imagescollide

i found some stuff on collisions, so i should be able to work that out when i've got a minute, but the other two?

BlitzMax will auto delete objects that are no longer referenced to. Release is only intended to tell the garbage collector that an integer handle is no longer being used, if your references are explicit (eg Blah:myType) then you never need to worry about freeing objects; the garbage collector will do everything for you.

Gosub is gone. Use functions.
Goto is there but does not work in Strict mode.

Setcolor affects drawimage now.

I spent a while trying to figure out why my image wasnt drawing, and it was because the color was setcolor 0,0,0

how to sort a type collection based on a number (like sorting bobs by Y)

Override the Compare method in your type. When you call SortList, it uses the Compare function to order the items based on the results of Compare. There's a tutorial *here*

For Before / After, use the InsertBeforeLink and InsertAfterLink method on the TLink object (see linkedlist.bmx in the module code). Sorry, I haven't got anything more "user-friendly", but that should be a start...

You can also use the First() and Last() methods like this:

a:myType = myType(myType_list.first())
a:myType = myType(myType_list.last())

Looks more complicated than it is. First() and Last() return an Object (not a Type 'thing'), so you have to convert it to a myType Type 'thing' using myType(object).

Imagebuffers no longer exist. The only way I have found to create composite images is to draw the images to the backbuffer, grabimage and cls before the main drawloop.

isnt that what piximaps are for? making those images that you want to manipulate in the manners you would a imagebuffer??

I only scimmed the docs on them but seemed that would be the case.

Yep but they don't provide the whole solution.
You can't draw 2 images to the same pixmap. You would have to draw both images to the backbuffer and then grabimage them into a pixmap.
There's a cost to convert image<->pixmap and grabimage.
Also, you can not directly use the backbuffer for for input to a merge with an imagebuffer unless you create a pixmap from it.

How can I easily port my array code to BMax.
I wonder if BM offers some "BP" compatibility mode.
Thanks

There's an "Import BB" option on the file menu. Try that (and let us know how good/bad it is).

The import option is really cool, and does most of the work.
Unfortunately, my code relyies heavily in the use of tcp streams and lots of 2d graphics operations that don't seem to have an equivalent in BM (MaskImage, for instance).

I am not saying that it does not work. On the contrary, the importer is a valuable tool but, unfortunately, direct conversion is not possible.

Thanks

I am trying to migrate my BlitzPlus app to BlitzMax. I don't see any of the routines to handle system events in BlitzMax. In particular I have the following that works well in BlitzPlus, but cannot see how to do it in Max:

Repeat
event = WaitEvent()

Select event
Case EVENT_KeyDown
gKeyPressed = EventData()
Select gKeyPressed
Case KEY_Escape
GameShutDown()

Case KEY_F
If gFullScreen=MODE_FullScreen Then
gFullScreen = MODE_Windowed
Else
gFullScreen = MODE_FullScreen
EndIf
SetupDisplay()

End Select

Case EVENT_MouseDown
Select EventData()
Case 1
gLeftMouseDown = True

Case 2
gRightMouseDown = True
End Select

Case EVENT_MouseUp
Select EventData()
Case 1
gLeftMouseDown = False

Case 2
gRightMouseDown = False
End Select

Case EVENT_Close
GameShutDown()

End Select

Until event = EVENT_Timer

Goto is bloody useful (not gosub tho), imagine a function:

Function testvar( ID )
   For A.BType = each BType
      if A<>Null
         if A\ID = ID then goto EndJump
      endif
   Next
   .EndJump

   ;perform check here
End Function


Does anyone know a thing that can do that in strict mode as if goto isnt desired what would be the way to do that. In some applications shaving a few millisecs off of going though thousands of items in a type after locating the one you wanted is prefered.

Same as you would in b3d...

Strict
...
Function testvar( ID )
   For Local A:BType = eachin BTypeList
     if A.ID = ID then Exit
   Next

   ...perform check here...
End Function
You can also do this...

Strict
...
Function testvar( ID )
   #Loopy
   while true
     Repeat
       For Local A:BType = eachin BTypeList
         if A.ID = ID then Exit Loopy
       Next
     forever
   Wend

   ...perform check here...
End Function


Does anyone know a thing that can do that in strict mode as if goto isnt desired what would be the way to do that. In some applications shaving a few millisecs off of going though thousands of items in a type after locating the one you wanted is prefered.


Well you can't actually run that code since there is no each in BMax, it's now EachIn and requires a TList, but it's dead simple to rearrange that to avoid the need for a goto.

Simply change the for next loop to a Repeat.. Until loop which loops until either you reach the last type or you find what you're looking for.

EG: ( B3d-style code to avoid complicating things with lists if you've not read up on them yet )

Function testvar( ID )
   Found=False
   A.BType=First BType
   Repeat
      If A\ID=ID
         Found=True
      Else
         A=After A
      End If
      
   Until (A=Null) or (Found=True)

   If Found=True
       ;perform check here
   Else
       ; don't do anything, we didn't find it.
   End If

   
   
End Function


another thing to note is remarks have changed from ; to '
Seperators have changed from : to ;

these things can be quite strange at first for seasoned blitzers

.

This one is minor, but a couple of non-obvious issues tripped me up for a bit. One of the first things that I wanted to do after buying BlitzMax was compile a simple console-based executable with input/processing/output. This is very easy to do in Blitz3D:

Name$ = Input( "What is your name? " )
Print "Hello, " + Name
Print
Print "Press any key to end."
WaitKey
End
The above code runs OK in BlitzMax's IDE (except for WaitKey not working), but is no good compiled. You'll see nothing from the .exe version unless you turn off "Build GUI App" (which is turned on by default) under Program|Build Options before building. But then, WaitKey won't work since the console doesn't respond to it - instead, the program hangs, allowing you to click the "X" to close the window (but that's not WaitKey's purpose). As long as you don't mind waiting for a specific key rather than any key, the fix is easy:

Name$ = Input( "What is your name? " )
Print "Hello, " + Name
Print
Input "Press [Enter] to end."
End
And so, BlitzMax retains a simple, console-based Hello World like any good BASIC should. The nice thing is that if "Framework BRL.StandardIO" is added at the top, the .exe is only 37K.

Is there also an equivalent for the "ExecFile" command?
Not that I use it much, but for some projects of mine it DOES come in handy.

If you search on 'execfile' then the same topic has come up a couple of times with extern solutions.
There's an update concerning the addition of createprocess()
from January (but I can't find it) and a query whether createprocess() can be used to simulate execfile().

Tric,
This is how I use ExecFile (windows only)

Extern "win32"
Function WinExec(lpCmdLine:Byte Ptr,nCmdShow:Int)
End Extern
WinExec("Notepad.exe",1)

A simple Alternative is the _system() command.

Usage:

_System("notepad.exe")

For further info search the Forum for '_system'

For further info search the Forum for '_system'


That's what I did, but only this thread appeared in the search results :(

Tric,
This is how I use ExecFile (windows only)

Extern "win32"
Function WinExec(lpCmdLine:Byte Ptr,nCmdShow:Int)
End Extern
WinExec("Notepad.exe",1)
[quote]

I'll keep that one in mind. Does it also work with URLS and files other than .exe that it searches for a program that can open it?
(Too bad I switched to Mac, but I can keep it in mind for my windows versions of products)

[quote]klepto2 (Posted 2005-08-08 11:59:14)

A simple Alternative is the _system() command.

Usage:

_System("notepad.exe")


i'll try that! ;)

no luck on mac os :( _system or system are not valid functions here :(

Blitz wiki to the rescue.

http://www.blitzwiki.org/index.php/System_Commands

It would be nice if the flushmem changes, etc. from the 1.14 release could be included... This tutorial will break brains if it's not updated =]

Just changed from old BB2D to Max, but some commands are not supported...

loopsound command
mp3 format
mpeg movie playback
joypad reading is different?

The ide search / replace is very poor.

Just changed from old BB2D to Max, but some commands are not supported...

loopsound command

There is a loop flag in LoadSound().

mp3 format

Use OGG instead. It offers better compression and no licence restrictions. Alternatively you can buy yourself an FMOD licence and use that.
mpeg movie playback
Well, its hardly a big loss.
joypad reading is different?
Its largely the same. If you're having problems then you should maybe start a thread in the BlitzMax Beginners Area or BlitzMax Programming forum to help resolve it.

Gfk,

Thanks, never spotted that loop flag.

Must readup on joypad commands...

Ok, joypad buttons now use values starting at 0,1,2,3 etc instead old blitz2d used 1,2,3,4 etc.

Keyhit/Keydown now sees RETURN and KEYPAD ENTER as the same key?

When setting up a windowed mode game, eg. 640x480 window - BlitzMax places your game window at the top-left of the desktop instead of centering it like Blitz2D.

Can the window be centered or moved automatically?

Is there a simple method to adapt a Blitz3D userlib into a Bmax one?