Orientation guide for existing Blitz users

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

BlitzSupport(Posted 2004) [#1]
(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!


BlitzSupport(Posted 2004) [#2]
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!)


dan_upright(Posted 2004) [#3]
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?


Michael Reitzenstein(Posted 2004) [#4]
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.


EOF(Posted 2004) [#5]
Gosub is gone. Use functions.
Goto is there but does not work in Strict mode.


Curtastic(Posted 2004) [#6]
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


Mark Tiffany(Posted 2005) [#7]
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...


Beaker(Posted 2005) [#8]
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).


tonyg(Posted 2005) [#9]
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.


RifRaf(Posted 2005) [#10]
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.


tonyg(Posted 2005) [#11]
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.


3DBuzzFan(Posted 2005) [#12]
How can I easily port my array code to BMax.
I wonder if BM offers some "BP" compatibility mode.
Thanks


Sledge(Posted 2005) [#13]
There's an "Import BB" option on the file menu. Try that (and let us know how good/bad it is).


3DBuzzFan(Posted 2005) [#14]
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


rogue(Posted 2005) [#15]
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


*(Posted 2005) [#16]
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.


Yan(Posted 2005) [#17]
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



Gabriel(Posted 2005) [#18]
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



*(Posted 2005) [#19]
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


Yan(Posted 2005) [#20]
.


WendellM(Posted 2005) [#21]
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.


Tricky(Posted 2005) [#22]
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.


tonyg(Posted 2005) [#23]
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().


assari(Posted 2005) [#24]
Tric,
This is how I use ExecFile (windows only)

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


klepto2(Posted 2005) [#25]
A simple Alternative is the _system() command.

Usage:

_System("notepad.exe")

For further info search the Forum for '_system'


Tricky(Posted 2005) [#26]
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! ;)


DannyD(Posted 2005) [#27]
no luck on mac os :( _system or system are not valid functions here :(


Jay Kyburz(Posted 2005) [#28]
Blitz wiki to the rescue.

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


Wiebo(Posted 2005) [#29]
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 =]


Eck(Posted 2006) [#30]
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.


GfK(Posted 2006) [#31]
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.


Eck(Posted 2006) [#32]
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?


Eck(Posted 2006) [#33]
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?


_33(Posted 2007) [#34]
Is there a simple method to adapt a Blitz3D userlib into a Bmax one?


Blue Steel(Posted 2010) [#35]
Are all these lessons / tips still valid.. being that they are 2 years old ?


Czar Flavius(Posted 2010) [#36]
Yes :)


epiblitikos(Posted 2010) [#37]
If anyone likes the shorthand type indicators as much as I do, see here...

In one of the other threads it mentions that the shorthand for Bytes and Shorts are @ and @@. That is, the following are equivalent.

Local abyte:Byte, ashort:Short

Local abyte@, ashort@@


And apparently $w and $z are shorthands, presumably for a wstrng and a zstring? If anyone has any info on them please post here. Thanks!


Matty(Posted 2010) [#38]
Hello,

Thought I'd try and download the blitzmax demo and see if I could compile my dungeon crawl game (see blitz showcase) in blitzmax, currently it is written with blitzplus.

After going through the code and changing all the type/struct differences (not quite sure how to delete type instances though...will typeinstance = null simply do it for me?) I had another question -

how do I use maskimage AFTER an image is loaded. Many times in my game i load an image, and simply check the pixel colour in the upper left corner (using readpixelfast on the imagebuffer) and set the mask for that image to that colour (I don't always use black) - do I have to load the image, send it to a pixmap, then read the pixel colour, then free the image (no freeimage command either!) then set the mask colour then reload it in again)..what am I missing here.

Also is there an equivalent of the Object/Handle commands in blitzmax - I use them all throughout my blitzplus/blitz3d code and I cannot see a way to do this?

And drawblock to draw an image without transparency..how is this done in blitzmax.


Jesse(Posted 2010) [#39]
I think this belongs in the beginners sections.

anyway nulling an instance of an object will cause the garbage collector to remove it automatically as long as there is no more references to it.
if you want to check it as you did in blitzbasic sort of it's fine the way you do it.
you can have a local variable in a function or a method grab the pixmap from an image with lockimage axcess the pixel do what you need to do with the image, when the function or method are exited the local variables will go out of scope and will be collected by the garbage collector along with any object(pixmap) in their scope. it is a different story if they are in a global as you might realize. the way to do it is to null it from the variable.

Only other variant is the lists. if you store something in a list you must remove it using ListRemove() or list.remove().


Matty(Posted 2010) [#40]
Thanks that kind of answers the first question (but raises some more) - but still the questions re:maskimage, object/handle, non-transparent drawing of images remain.

New questions then:

If I create a function and in that function create a local bank or image and I return the handle to that bank or image from the function does that mean that the bank/image etc is not destroyed upon exiting the function.


Jesse(Posted 2010) [#41]
you have to use SetMaskColor to change the mask to a different color.

and as long as there is a handle to an object it will not be collected by the garbage collector so if you create it in a function or method with a local variable, passed it to the main program, the object will remain in memory as long as there is a handle to it.


Matty(Posted 2010) [#42]
I don't think you've understood my questions..oh well I'm probably going to stick with blitzplus anyway.


Jesse(Posted 2010) [#43]
you can do it like this:
Local image:TImage = LoadImage("image.png")
Local pixmap:TPixmap = LockImage(image)
Local mask:Int = pixmap.ReadPixel(0,0)
Local blue:Int =  mask & $FF
Local green:Int = (mask & $ff00) Shr 8
Local red:Int = (mask & $ff0000) Shr 16
SetMaskColor red, green, blue 

image = LoadImage(pixmap)



Matty(Posted 2010) [#44]
What about the undocumented blitz3d/blitzplus commands "object & handle"? Is there an equivalent function for retrieving a specific type instance?

And drawing images with no transparency?(blitzplus/blitz3d drawblock image,x,y)

Thanks,


Jesse(Posted 2010) [#45]
>"object & handle"
you just type cast it :
local obj:object =  baddy

local enemy:TmyType = Tmytype(obj)

> "drawBlock"
SetBlend SOLIDBLEND 

look up SetBlend for other options.

I am having a bit of a hard time trying to figure out exactly what you want. if you can post some code maybe I can help you better.


Matty(Posted 2010) [#46]
Sorry Jesse, I'd never heard the term "type cast" before. But I use the object & handle feature of blitz3d/blitzplus heavily..usually storing the type handle in either a bank or array for quick an easy access to the type instance, and if this "type casting' feature does it then that is good.

I'm not trying to do anything specific, just trying to find a way to convert my code for a particular, fully working, project in blitzplus to blitzmax - although it's not as simple as it would seem...there's a lot of differences between the way I do things in blitzplus and the way blitzmax would prefer I do them.


Matty(Posted 2015) [#47]
Oh...how time flies....and how much you can learn in that time. (I just noticed my name as the last poster....five years ago....how much we learn...)