apptitle

BlitzMax Forums/BlitzMax Programming/apptitle

anyway to change the title? easy question

if you get create a function that exports the hwnd from the bglcreatecontext c file then you can do it on windows with the WinAPI function SetWindowText_( hwnd, title ).
didn't find any internal function as windowed support isn't really in. actually it is only meant for debugging from what the doc / source says

Nice idea but shouldn't we all be creating cross-platform software now?

Yepp
But windowed isn't in so far. I think when it is really in we will have this functions provided as well :)

is there a function to set the window title before the window is created? because without this function the user will see the default title for a small time.

I wrote a little module with some commands including SetAppTitle here: http://www.blitzbasic.com/Community/posts.php?topic=43341

it works for Mac and Windows currently (look near the bottom of the thread for the latest version).

thank you, Perturbatio, but if I run the following code the user can still see the default title ("BlitzGLWimdow") for a small time.
Strict

Import Pert.AppFuncs

Graphics 200 , 200 , 0
'At this program step the title of the window is "BlitzGLWindow"
SetAppTitle "MyApp"
'here the title is "MyApp"
While Not KeyHit ( KEY_ESCAPE )
  PollSystem
Wend

If I call the SetAppTitle-function before I call the Graphics-command the window title is all the time "BlitzGLWindow".

I notice there's no AppTitle in the final Windows release, so are we still not to use windowed mode for releases?

The only way to change it before the window shows is to either:
Hack the C source that contains the Graphics command
OR
Create your own OpenGL window


I notice there's no AppTitle in the final Windows release, so are we still not to use windowed mode for releases?



From the docs:

A depth value of 0 enables 'windowed mode'. This special mode is currently intended for debugging purposes only and should not be used for release builds. Improved support for windowed modes will be added shortly.



thank you, Perturbatio, I've changed some files and it works!
(I added 4 lines from your code so that the function works as well as the AppTitle-function in Blitz3D(that means it works before and while the window is opened))
here is the code:

/mod/brl.mod/blitzgl.mod/blitzgl.win32.c:

#include <windows.h>

#include <gl/gl.h>

enum{
	BGL_FULLSCREEN=1,
	BGL_BACKBUFFER=2,
	BGL_ALPHABUFFER=4,
	BGL_DEPTHBUFFER=8,
	BGL_STENCILBUFFER=16,
	BGL_ACCUMBUFFER=32
};

static const char *CLASS_NAME="BlitzGL Window Class";

static HDC context_hdc;
static HWND context_hwnd;
static HGLRC context_hglrc;

static int fullScreen;
static const char*windowname="BlitzGLWindow";
static DEVMODE devmode;
static int active,started,font_lists;

typedef BOOL (APIENTRY * WGLSWAPINTERVALEXT) (int);
static WGLSWAPINTERVALEXT wglSwapIntervalEXT;

void bglDeleteContext( int context );

static void bglExit(){
	bglDeleteContext(0);
}

static void poll(){
	MSG msg;
	while( PeekMessage( &msg,0,0,0,PM_REMOVE ) ){
		TranslateMessage( &msg );
		DispatchMessage( &msg );
	}
}

_stdcall long wndProc( HWND hwnd,UINT msg,WPARAM wp,LPARAM lp ){
	switch( msg ){
	case WM_CLOSE:
		return 0;
	case WM_PAINT:
		ValidateRect( hwnd,0 );
		return 0;
	case WM_SETFOCUS:
		if( devmode.dmSize && !fullScreen ){
			if( ChangeDisplaySettings( &devmode,CDS_FULLSCREEN )==DISP_CHANGE_SUCCESSFUL ){
				fullScreen=1;
			}else if( devmode.dmFields&DM_DISPLAYFREQUENCY ){
				devmode.dmDisplayFrequency=0;
				devmode.dmFields&=~DM_DISPLAYFREQUENCY;
				if( ChangeDisplaySettings( &devmode,CDS_FULLSCREEN )==DISP_CHANGE_SUCCESSFUL ){
					fullScreen=1;
				}
			}
		}
		return 0;
	case WM_KILLFOCUS:
		if( devmode.dmSize && fullScreen ){
			ChangeDisplaySettings( 0,CDS_FULLSCREEN );
			ShowWindow( hwnd,SW_MINIMIZE );
			fullScreen=0;
		}
		return 0;
	}
	return DefWindowProc( hwnd,msg,wp,lp );
}

void bglDeleteContext( context ){
	if( !active ) return;
	wglDeleteContext( context_hglrc );
	ChangeDisplaySettings( 0,CDS_FULLSCREEN );
	DestroyWindow( context_hwnd );
	active=0;
}

int bglDisplayModes( int *modes,int size ){

	int count=size/16;
	int *end=modes+count*4,i=0,n=0;

	while( modes!=end ){

		DEVMODE	mode;
		mode.dmSize=sizeof(DEVMODE);
		mode.dmDriverExtra=0;

		if( !EnumDisplaySettings(0,i++,&mode) ) break;

		if( mode.dmBitsPerPel<16 ) continue;

		*modes++=mode.dmPelsWidth;
		*modes++=mode.dmPelsHeight;
		*modes++=mode.dmBitsPerPel;
		*modes++=mode.dmDisplayFrequency;
		++n;
	}
	return n;
}

static void setPfd( PIXELFORMATDESCRIPTOR *pfd,int flags ){

	memset( pfd,0,sizeof(*pfd) );

	pfd->nSize=sizeof(pfd);
	pfd->nVersion=1;
	pfd->cColorBits=1;
	pfd->iPixelType=PFD_TYPE_RGBA;
	pfd->iLayerType=PFD_MAIN_PLANE;
	pfd->dwFlags=PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL;

	pfd->dwFlags|=(flags & BGL_BACKBUFFER) ? PFD_DOUBLEBUFFER : 0;
	pfd->cAlphaBits=(flags & BGL_ALPHABUFFER) ? 1 : 0;
	pfd->cDepthBits=(flags & BGL_DEPTHBUFFER) ? 1 : 0;
	pfd->cStencilBits=(flags & BGL_STENCILBUFFER) ? 1 : 0;
	pfd->cAccumBits=(flags & BGL_ACCUMBUFFER) ? 1 : 0;
}

static void createWindowedContext( int width,int height,int flags ){

	long pf;
	PIXELFORMATDESCRIPTOR pfd;
	RECT rect={0,0,width,height};
	int ex_style=0,style=WS_VISIBLE|WS_CAPTION;
	
	devmode.dmSize=0;

	AdjustWindowRectEx( &rect,style,0,ex_style );
	
	context_hwnd=CreateWindowEx( 
		ex_style,CLASS_NAME,windowname,
		style,CW_USEDEFAULT,CW_USEDEFAULT,
		rect.right-rect.left,rect.bottom-rect.top,
		0,0,GetModuleHandle(0),0 );
		
	setPfd( &pfd,flags );

	context_hdc=GetDC( context_hwnd );
	pf=ChoosePixelFormat( context_hdc,&pfd );
	if( !pf ){
		DestroyWindow( context_hwnd );
		return;
	}
	SetPixelFormat( context_hdc,pf,&pfd );
	context_hglrc=wglCreateContext( context_hdc );
	wglMakeCurrent( context_hdc,context_hglrc );

	active=1;
}

static void createFullscreenContext( int width,int height,int depth,int hertz,int flags ){

	long pf;
	PIXELFORMATDESCRIPTOR pfd;

	devmode.dmSize=sizeof(devmode);
	devmode.dmPelsWidth=width;
	devmode.dmPelsHeight=height;
	devmode.dmBitsPerPel=depth;
	devmode.dmFields=DM_PELSWIDTH|DM_PELSHEIGHT|DM_BITSPERPEL;
	if( hertz ){
		devmode.dmDisplayFrequency=hertz;
		devmode.dmFields|=DM_DISPLAYFREQUENCY;
	}
	context_hwnd=CreateWindowEx( 
		WS_EX_TOPMOST,CLASS_NAME,windowname,
		WS_VISIBLE|WS_POPUP|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,0,0,width,height,0,0,GetModuleHandle(0),0 );

	setPfd( &pfd,flags );

	context_hdc=GetDC( context_hwnd );
	pf=ChoosePixelFormat( context_hdc,&pfd );
	if( !pf ){
		DestroyWindow( context_hwnd );
		return;
	}
	SetPixelFormat( context_hdc,pf,&pfd );
	context_hglrc=wglCreateContext( context_hdc );
	wglMakeCurrent( context_hdc,context_hglrc );

	active=1;
}

int bglCreateContext( int width,int height,int depth,int hertz,int flags ){

	bglDeleteContext( 0 );

	if( !started ){
	    WNDCLASS wc={0};
		wc.style=CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
		wc.lpfnWndProc=(WNDPROC)wndProc;
		wc.hInstance=GetModuleHandle(0);
		wc.lpszClassName=CLASS_NAME;
		wc.hCursor=(HCURSOR)LoadCursor( 0,IDC_ARROW );
		wc.hbrBackground=0;//(HBRUSH)GetStockObject(BLACK_BRUSH);
		if( !RegisterClass( &wc ) ) exit(-1);
		atexit( bglExit );
		started=1;
	}

	if( flags & BGL_FULLSCREEN ){
		createFullscreenContext( width,height,depth,hertz,flags );
	}else{
		createWindowedContext( width,height,flags );
	}

	if( !active ) return 0;

	wglSwapIntervalEXT=(WGLSWAPINTERVALEXT)wglGetProcAddress("wglSwapIntervalEXT");

	bglSetSwapInterval( 0 );

	return 1;
}

int bglSetSwapInterval( int n ){
	return wglSwapIntervalEXT && wglSwapIntervalEXT(n);
}

void bglSwapBuffers(){
	if( !active ) return;
	SwapBuffers( context_hdc );
}

void bglSetMouseVisible( int visible ){
	int n;
	if( !active ) return;
	n=ShowCursor( visible );
	if( n<-1 || n>0 ) ShowCursor(!visible);
}

int bglFixedFontBitmaps(){
	HFONT hfont,t_font;
	HDC hdc;
		
	if( !active ) return 0;

	if( font_lists ) return font_lists;

	hfont=CreateFont( 
		14,0,0,0,
		FW_REGULAR,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
		DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"fixedsys" );

	hdc=CreateCompatibleDC(0);
	t_font=(HFONT)SelectObject( hdc,hfont );

	font_lists=glGenLists( 256 );
	wglUseFontBitmaps( hdc,0,255,font_lists );

	SelectObject( hdc,t_font );
	DeleteDC( hdc );
	DeleteObject( hfont );

	return font_lists;
}



/mod/brl.mod/blitzgl.mod/blitzgl.bmx:

Strict

Rem
bbdoc: BlitzGL
end rem
Module BRL.BlitzGL

ModuleInfo "Version: 1.05"
ModuleInfo "Author: Mark Sibly"
ModuleInfo "License: Blitz Shared Source Code"
ModuleInfo "Copyright: Blitz Research Ltd"
ModuleInfo "Modserver: BRL"

ModuleInfo "History: 1.05 Release"
ModuleInfo "History: 1.04 Release"
ModuleInfo "History: Fixed C Compiler warnings"

Import Pub.OpenGL
Import BRL.Pixmap

?MacOS
Import "blitzgl.macosx.m"
?Win32
Import "blitzgl.win32.c"
?Linux
Import "blitzgl.linux.c"
?

Extern

Const BGL_FULLSCREEN=1
Const BGL_BACKBUFFER=2
Const BGL_ALPHABUFFER=4
Const BGL_DEPTHBUFFER=8
Const BGL_STENCILBUFFER=16
Const BGL_ACCUMBUFFER=32

Rem
bbdoc: Get available display modes
returns: Number of available display modes
about:
The region of memory pointed to by @buf is filled with a series of 16 byte [width:Int,height:Int,depth:Int,hertz:Int]
structures. No more than @size bytes are written to @buf.
End Rem
Function bglDisplayModes( buf:Int Ptr,size )

?win32
Rem
bbdoc: Name of the next created context
about: this variable contains the title of the next context created with #bglCreateContext
EndRem
Global bglAppTitle:Byte Ptr = "windowtitle"
?

Rem
bbdoc: Create GL context
returns: True if successful
about: @flags can be any combination of:<br>
<br>
<table>
<tr><th>Flag value</th><th>Effect</th></tr>
<tr><td><font class=token>BGL_FULLSCREEN</font></td><td>Create a full screen context</td></tr>
<tr><td><font class=token>BGL_BACKBUFFER</font></td><td>Create a context with a backbuffer</td></tr>
<tr><td><font class=token>BGL_ALPHABUFFER</font></td><td>Create a context with an alpha buffer</td></tr>
<tr><td><font class=token>BGL_DEPTHBUFFER</font></td><td>Create a context with a depth buffer</td></tr>
<tr><td><font class=token>BGL_STENCILBUFFER</font></td><td>Create a context with a stencil buffer</td></tr>
<tr><td><font class=token>BGL_ACCUMBUFFER</font></td><td>Create a context with an accumulation buffer</td></tr>
</table>
<br>
To combine multiple flags, use the <font class=token>|</font> operator. 
End Rem
Function bglCreateContext( width,height,depth=16,hertz=0,flags=BGL_FULLSCREEN|BGL_BACKBUFFER|BGL_DEPTHBUFFER )

Rem
bbdoc: Delete GL context
about: By default, deletes current context.
End Rem
Function bglDeleteContext( context=0 )

Rem
bbdoc: Set GL swap interval
returns: True if successful, else false. Not all OpenGL drivers may support this function.
End Rem
Function bglSetSwapInterval( interval )

Rem
bbdoc: Swap GL buffers
about: The current OpenGL context must have been created with the BGL_BACKBUFFER flag.
End Rem
Function bglSwapBuffers()

Rem
bbdoc: Show or hide GL mouse pointer
End Rem
Function bglSetMouseVisible( visible )

Rem
bbdoc: Create GL font bitmaps
returns: Base display list name containing first glyph
End Rem
Function bglFixedFontBitmaps()

End Extern

'----- Helper Functions -----

Rem
bbdoc: Helper function to calculate nearest valid texture size
about: This functions rounds @width and @height up to the nearest valid texture size
end rem
Function bglAdjustTexSize( width Var,height Var )
	Function Pow2Size( n )
		Local t=1
		While t<n
			t:*2
		Wend
		Return t
	End Function
	width=Pow2Size( width )
	height=Pow2Size( height )
	Repeat
		Local t
		glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null
		glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t
		If t Return
		If width=1 And height=1 RuntimeError "Unable to calculate tex size"
		If width>1 width:/2
		If height>1 height:/2
	Forever
End Function

Rem
bbdoc: Helper function to create a texture from a pixmap
returns: Integer GL Texture name
about: @pixmap is resized to a valid texture size before conversion.
end rem
Function bglTexFromPixmap( pixmap:TPixmap,mipmap=True )

	If pixmap.format<>PF_RGBA8888 pixmap=pixmap.Convert( PF_RGBA8888 )

	Local width=pixmap.width,height=pixmap.height
	bglAdjustTexSize width,height
	If width<>pixmap.width Or height<>pixmap.height pixmap=ResizePixmap( pixmap,width,height )
	
	Local old_name,old_row_len
	glGetIntegerv GL_TEXTURE_BINDING_2D,Varptr old_name
	glGetIntegerv GL_UNPACK_ROW_LENGTH,Varptr old_row_len

	Local name
	glGenTextures 1,Varptr name
	glBindtexture GL_TEXTURE_2D,name
	
	Local mip_level
	Repeat
		glPixelStorei GL_UNPACK_ROW_LENGTH,pixmap.pitch/BytesPerPixel[pixmap.format]
		glTexImage2D GL_TEXTURE_2D,mip_level,GL_RGBA8,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
		If Not mipmap Exit
		If width=1 And height=1 Exit
		If width>1 width:/2
		If height>1 height:/2
		pixmap=ResizePixmap( pixmap,width,height )
		mip_level:+1
	Forever
	
	glBindTexture GL_TEXTURE_2D,old_name
	glPixelStorei GL_UNPACK_ROW_LENGTH,old_row_len

	Return name

End Function

Rem
bbdoc: Helper function to output some simple 8x16 font text
about:
Draws text relative to top-left of current viewport.<br>
<br>
This function is intended for debugging purposes only - performance is unlikely to be stellar.
end rem
Function bglDrawText( text$,x,y )

	Local mvMatrix![16],pjMatrix![16],matMode[1],vp[4]

	glGetIntegerv GL_VIEWPORT,vp
	glGetIntegerv GL_MATRIX_MODE,matMode
	glGetDoublev GL_MODELVIEW_MATRIX,mvMatrix
	glGetDoublev GL_PROJECTION_MATRIX,pjMatrix
	
	glMatrixMode GL_MODELVIEW
	glLoadIdentity
	glMatrixMode GL_PROJECTION
	glLoadIdentity
	
	y=vp[3]-y-16
	x=x-vp[2]/2+vp[0]
	y=y-vp[3]/2+vp[1]
	
	Local h,lists=bglFixedFontBitmaps()
	glRasterPos2i 0,0
	glBitmap 0,0,0,0,x,y,Null
	For Local k=0 Until Len(text)
		Local n=text[k]
		If n>=0 And n<=255 glCallList lists+n
	Next
	
	glMatrixMode GL_PROJECTION
	glLoadMatrixd pjMatrix
	glMatrixMode GL_MODELVIEW
	glLoadMatrixd mvMatrix
	glMatrixMode matMode[0]
	
End Function



/mod/brl.mod/max2d.mod/max2d.bmx:

Strict

Rem
bbdoc: Max2D
End Rem
Module BRL.Max2D

ModuleInfo "Version: 1.08"
ModuleInfo "Author: Mark Sibly, Simon Armstrong"
ModuleInfo "License: Blitz Shared Source Code"
ModuleInfo "Copyright: Blitz Research Ltd"
ModuleInfo "Modserver: BRL"

ModuleInfo "History: 1.08 Release"
ModuleInfo "History: Graphics now does an EndGraphics first"
ModuleInfo "History: 1.07 Release"
ModuleInfo "History: 1.06 Release"
ModuleInfo "History: Added GetLineWidth#()"
ModuleInfo "History: Added GetClsColor( red Var,green Var,blue Var )"
ModuleInfo "History: Fixed Object reference bug in Collision system"
ModuleInfo "History: 1.05 Release"
ModuleInfo "History: Fixed AnimImage collisions"
ModuleInfo "History: Fixed ImagesCollide/ImagesCollide2 parameter types"

Import BRL.System

Import "image.bmx"
Import "driver.bmx"
Import "imagefont.bmx"

Private

Global graphics_active
Global graphics_width,graphics_height
Global graphics_depth,graphics_hertz
Global color_red,color_blue,color_green
Global color_alpha#
Global clscolor_red,clscolor_green,clscolor_blue
Global line_width#
Global mask_red,mask_green,mask_blue
Global tform_rot#,tform_scale_x#,tform_scale_y#
Global tform_ix#,tform_iy#,tform_jx#,tform_jy#
Global viewport_x,viewport_y,viewport_w,viewport_h
Global origin_x#,origin_y#
Global handle_x#,handle_y#
Global image_font:TImageFont,default_font:TImageFont
Global blend_mode
Global auto_midhandle
Global auto_imageflags;

Function UpdateTransform()
	Local s#=Sin(tform_rot)
	Local c#=Cos(tform_rot)
	tform_ix= c*tform_scale_x
	tform_iy=-s*tform_scale_y
	tform_jx= s*tform_scale_x
	tform_jy= c*tform_scale_y
	blitz2d_driver.SetTransform tform_ix,tform_iy,tform_jx,tform_jy
	SetCollisions2DTransform tform_ix,tform_iy,tform_jx,tform_jy
End Function

?win32
Extern "Win32"
  Function _SetWindowText(hwnd:Int, lpString:Byte Ptr) = "SetWindowTextA@8"
  Function _GetActiveWindow() = "GetActiveWindow@0"
EndExtern
?
Public
?win32
Rem
bbdoc: Set applications title
about: Use this function to set the name of the application.
The  application name is the window title in windowed mode
and shown in taskbar when the program is in fullscreen mode
and the user switched to another application( with ALT+TAB ).
EndRem
Function SetAppTitle ( title$ )
  bglAppTitle = title.ToCString ( )
  Local _CurrentWinHandle = _GetActiveWindow()
  _SetWindowText(_CurrentWinHandle, title.toCString())
EndFunction
?

Rem
bbdoc: Get number of available graphics modes
returns: Number of available graphics modes
about: Use #GetGraphicsMode to obtain information about an individual graphics mode
End Rem
Function CountGraphicsModes()
	Return GraphicsModes.length
End Function

Rem
bbdoc: Get information about a graphics mode
about: #GetGraphicsMode returns information about a specific graphics mode. @mode should be
in the range 0 (inclusive) to the value returned by #CountGraphicsModes (exclusive).
end rem
Function GetGraphicsMode( mode,width Var,height Var,depth Var,hertz Var )
	Local gmode:TGraphicsMode=GraphicsModes[mode]
	width=gmode.width
	height=gmode.height
	depth=gmode.depth
	hertz=gmode.hertz
End Function

Rem
bbdoc: Determine if a graphics mode exists
returns: True if a matching graphics mode is found
about: A value of 0 for any of @width, @height, @depth or @hertz will cause that
parameter to be ignored.
end rem
Function GraphicsModeExists( width,height,depth=0,hertz=0 )
	For Local mode=0 Until GraphicsModes.length
		Local gmode:TGraphicsMode=GraphicsModes[mode]
		If width And width<>gmode.width Continue
		If height And height<>gmode.height Continue
		If depth And depth<>gmode.depth Continue
		If hertz And hertz<>gmode.hertz Continue
		Return True
	Next
	Return False
End Function

Rem
bbdoc: Set Graphics mode
about:
Sets the current Max2D graphics mode. This command must be executed before any other Max2D commands.
@width and @height specify the size, in pixels, of the graphics mode, @depth specifies the bit depth and @hertz
specifies the refresh rate.<br>
<br>
A @depth value of 0 enables 'windowed mode'. This special mode is currently intended for 
debugging purposes only and should not be used for release builds. Improved support for 
windowed modes will be added shortly.<br>
<br>
Changing graphics modes will automatically invalidate all images and image fonts. These must
be reloaded or recreated if you wish to use them again in another graphics mode.
End Rem
Function Graphics( width,height,depth=16,hertz=60 )
	If depth And Not GraphicsModeExists( width,height,0,0 )
		RuntimeError "Graphics mode does not exist"
	EndIf 
	EndGraphics
	blitz2d_driver.Graphics width,height,depth,hertz
	graphics_width=width
	graphics_height=height
	graphics_depth=depth
	graphics_hertz=hertz
	SetBlend MASKBLEND
	SetColor 255,255,255
	SetClsColor 0,0,0
	SetMaskColor 0,0,0
	SetAlpha 1
	SetOrigin 0,0
	SetHandle 0,0
	SetViewport 0,0,width,height
	SetTransform 0,1,1
	AutoMidHandle False
	AutoImageFlags MASKEDIMAGE|FILTEREDIMAGE
	default_font=TImageFont.CreateDefault()
	image_font=default_font
	graphics_active=True
End Function

Rem
bbdoc: End Graphics mode
about:
EndGraphics closes the current full screen 2D graphics display created with the #Graphics
command.<br>
<br>
Changing graphics modes will automatically invalidate all images and image fonts. These must
be reloaded or recreated if you wish to use them again in another graphics mode.
end rem
Function EndGraphics()
	If Not graphics_active Return
	blitz2d_driver.EndGraphics
	graphics_width=0
	graphics_height=0
	image_font=Null
	default_font=Null
	graphics_active=False
End Function

Rem
bbdoc: Get width of Graphics mode.
returns: The width, in pixels, of the current Graphics mode.
End Rem
Function GraphicsWidth()
	Return graphics_width
End Function

Rem
bbdoc: Get height of Graphics mode.
returns: The height, in pixels, of the current Graphics mode.
End Rem
Function GraphicsHeight()
	Return graphics_height
End Function

Rem
bbdoc: Get width, height, depth and hertz of current Graphics mode.
returns: The width and height in pixels, the depth in bits and the frequency in hertz of the current Graphics mode.
End Rem
Function GetGraphics( width Var,height Var,depth Var,hertz Var )
	width=graphics_width
	height=graphics_height
	depth=graphics_depth
	hertz=graphics_hertz
End Function

Rem
bbdoc: Swap front and back buffers
about: Flip can only be used after a call to #Graphics and must be executed to show 
the results of any drawing commands.<p>
BlitzMax uses a double buffered graphics system where all drawing is done to a <i>Back Buffer</i> 
and what is shown on the screen is known as the <i>Front Buffer</i>. #Flip causes the buffers 
to be swapped allowing for fast flicker free graphics animation.
End Rem
Function Flip()

	blitz2d_driver.Flip

End Function

Rem
bbdoc: Clear back buffer
about: Clears the back buffer to the current #SetClsColor. The default ClsColor is Black.<p>
After a #Flip command the contents of the back buffer is undefined, most often containing
the contents of the last <i>Front Buffer</i> making a call to Cls() essential before calling
any drawing commands in order to create the next frame of graphics for display.
End Rem
Function Cls()
	blitz2d_driver.Cls
End Function

Rem
bbdoc: Set current #Cls color
about:
The @red, @green and @blue parameters should be in the range of 0 to 255.
End Rem
Function SetClsColor( red,green,blue )
	clscolor_red=red
	clscolor_green=green
	clscolor_blue=blue
	blitz2d_driver.SetClsColor red,green,blue
End Function

Rem
bbdoc: Get red, green and blue component of current cls color.
returns: Red, green and blue values in the range 0..255 in the variables supplied.
End Rem
Function GetClsColor( red Var,green Var,blue Var )
	red=clscolor_red
	green=clscolor_green
	blue=clscolor_blue
End Function

Rem
bbdoc: Plot a pixel
about:
Sets the color of a single pixel on the back buffer to the current drawing color
defined with the #SetColor command. Other commands that affect the operation of
#Plot include #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha.
End Rem
Function Plot( x#,y# )
	blitz2d_driver.Plot x+origin_x,y+origin_y
End Function

Rem
bbdoc: Draw a rectangle
about:
Sets the color of a rectangular area of pixels using the current drawing color
defined with the #SetColor command.<p>
Other commands that affect the operation of #DrawRect include #SetHandle, #SetScale,
#SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha.
End Rem
Function DrawRect( x#,y#,width#,height# )
	blitz2d_driver.DrawRect handle_x,handle_y,handle_x+width,handle_y+height,x+origin_x,y+origin_y
End Function

Rem
bbdoc: Draw a line
about:
#DrawLine draws a line from @x,@y to @x2,@y2 with the current drawing color.<p>
BlitzMax commands that affect the drawing of lines include #SetLineWidth, #SetColor, #SetHandle, 
#SetScale, #SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha.
The optional @draw_last_pixel parameter can be used to control whether the last pixel of the line is drawn or not.
Not drawing the last pixel can be useful if you are using certain blending modes.
End Rem 
Function DrawLine( x#,y#,x2#,y2#,draw_last_pixel=True )
	blitz2d_driver.DrawLine handle_x,handle_y,handle_x+x2-x,handle_y+y2-y,x+origin_x,y+origin_y
	If Not draw_last_pixel Return
	Local px#=handle_x+x2-x,py#=handle_y+y2-y
	blitz2d_driver.Plot px*tform_ix+py*tform_iy+x+origin_x,px*tform_jx+py*tform_jy+y+origin_y
End Function

Rem
bbdoc: Draw an oval
about:
#DrawOval draws an oval that fits in the rectangular area defined by @x, @y, @width 
and @height parameters.<p>
BlitzMax commands that affect the drawing of ovals include #SetColor, #SetHandle, 
#SetScale, #SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha.
End Rem
Function DrawOval( x#,y#,width#,height# )
	blitz2d_driver.DrawOval handle_x,handle_y,handle_x+width,handle_y+height,x+origin_x,y+origin_y
End Function

Rem
bbdoc: Draw a polygon
about:
#DrawPoly draws a polygon with corners defined by an array of x#,y# coordinate pairs.<p>
BlitzMax commands that affect the drawing of polygons include #SetColor, #SetHandle, 
#SetScale, #SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha.
End Rem
Function DrawPoly( xy#[] )
	blitz2d_driver.DrawPoly xy,handle_x,handle_y,origin_x,origin_y
End Function

Rem
bbdoc: Draw text
about:
#DrawText prints strings at position @x,@y of the graphics display using
the current image font specified by the #SetImageFont command.<p>
Other commands that affect #DrawText include #SetColor, #SetHandle, 
#SetScale, #SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha.
End Rem
Function DrawText( t$,x#,y# )
	image_font.Draw t,..
	x+origin_x+handle_x*tform_ix+handle_y*tform_iy,..
	y+origin_y+handle_x*tform_jx+handle_y*tform_jy,..
	tform_ix,tform_iy,tform_jx,tform_jy
End Function

Rem
bbdoc: Draw an image to the back buffer
about: Drawing is affected by the current blend mode, color, scale and rotation.<br>
<br>
If the blend mode is ALPHABLEND, then the image is also affected by the current alpha value.
End Rem
Function DrawImage( image:TImage,x#,y#,frame=0 )
	Local x0#=-image.handle_x,x1#=x0+image.width
	Local y0#=-image.handle_y,y1#=y0+image.height
	image.frames[frame].Draw x0,y0,x1,y1,x+origin_x,y+origin_y
End Function

Rem
bbdoc: Draw an image to a rectangular area of the back buffer
about: Drawing is affected by the current blend mode, color, scale and rotation.<br>
<br>
If the blend mode is ALPHABLEND, then the image is also affected by the current alpha value.
End Rem
Function DrawImageRect( image:TImage,x#,y#,w#,h#,frame=0 )
	Local x0#=-image.handle_x,x1#=x0+w
	Local y0#=-image.handle_y,y1#=y0+h
	image.frames[frame].Draw x0,y0,x1,y1,x+origin_x,y+origin_y
End Function

Rem
bbdoc: Draw an image in a tiled pattern
about: #TileImage draws an image in a repeating, tiled pattern, filling the current viewport.
End Rem
Function TileImage( image:TImage,x#=0#,y#=0#,frame=0 )
	blitz2d_driver.SetTransform 1,0,0,1

	Local w=image.width
	Local h=image.height
	Local ox=viewport_x-w+1
	Local oy=viewport_y-h+1
	Local px#=x+origin_x-image.handle_x
	Local py#=y+origin_y-image.handle_y
	Local fx#=px-Floor(px)
	Local fy#=py-Floor(py)
	Local tx=Floor(px)-ox
	Local ty=Floor(py)-oy

	If tx>=0 tx=tx Mod w + ox Else tx=w - -tx Mod w + ox
	If ty>=0 ty=ty Mod h + oy Else ty=h - -ty Mod h + oy

	Local vr=viewport_x+viewport_w,vb=viewport_y+viewport_h

	Local iy=ty
	While iy<vb
		Local ix=tx
		While ix<vr
			image.frames[frame].Draw 0,0,w,h,ix+fx,iy+fy
			ix=ix+w
		Wend
		iy=iy+h
	Wend

	UpdateTransform

End Function

Rem
bbdoc: Set current color
about:
The #SetColor command affects the color of #Plot, #DrawRect, #DrawLine, #DrawText
and #DrawPoly.<p>
The @red, @green and @blue parameters should be in the range of 0 to 255.
End Rem
Function SetColor( red,green,blue )
	color_red=red
	color_green=green
	color_blue=blue
	blitz2d_driver.SetColor red,green,blue
End Function

Rem
bbdoc: Get red, green and blue component of current color.
returns: Red, green and blue values in the range 0..255 in the variables supplied.
End Rem
Function GetColor( red Var,green Var,blue Var )
	red=color_red
	green=color_green
	blue=color_blue
End Function

Rem
bbdoc: Set current blend mode
about: 
SetBlend controls how pixels are combined with existing pixels in the back buffer when drawing
commands are used in BlitzMax.<p>
@blend should be one of:
<table>
<tr><th>Blend mode</th><th>Effect</th></tr>
<tr><td>SOLIDBLEND</td><td>Pixels overwrite existing backbuffer pixels</td></tr>
<tr><td>MASKBLEND</td><td>Pixels are drawn only if their alpha component is greater than .5</td></tr>
<tr><td>ALPHABLEND</td><td>Pixels are alpha blended with existing backbuffer pixels</td></tr>
<tr><td>LIGHTBLEND</td><td>Pixel colors are added to backbuffer pixel colors, giving a 'lighting' effect</td></tr>
<tr><td>SHADEBLEND</td><td>Pixel colors are multiplied with backbuffer pixel colors, giving a 'shading' effect</td></tr>
</table>
End Rem
Function SetBlend( blend )
	blend_mode=blend
	blitz2d_driver.SetBlend blend
End Function

Rem
bbdoc: Get current blendmode setting
returns: 0 (SOLIDBLEND), 1 (MASKBLEND) ,2 (ALPHABLEND), 3 (LIGHTBLEND) or 4 (SHADEBLEND).
End Rem
Function GetBlend()
	Return blend_mode
End Function

Rem
bbdoc: Set current alpha level
about: @alpha should be in the range 0 to 1.<p>
@alpha controls the transparancy level when the ALPHABLEND blend mode is in effect.
The range from 0.0 to 1.0 allows a range of transparancy from completely transparent 
to completely solid.
End Rem
Function SetAlpha( alpha# )
	color_alpha=alpha
	blitz2d_driver.SetAlpha alpha
End Function

Rem
bbdoc: Get current alpha setting.
returns: the current alpha value in the range 0..1.0 
End Rem
Function GetAlpha#()
	Return color_alpha
End Function

Rem
bbdoc: Sets pixel width of lines drawn with the #DrawLine command
End Rem
Function SetLineWidth( width# )
	line_width=width
	blitz2d_driver.SetLineWidth width
End Function

Rem
bbdoc: Get line width
returns: Current line width, in pixels
End Rem
Function GetLineWidth#()
	Return line_width
End Function

Rem
bbdoc: Set current mask color
about: The current mask color is used to build an alpha mask when images are loaded or modified.
The @red, @green and @blue parameters should be in the range of 0 to 255.
End Rem
Function SetMaskColor( red,green,blue )
	mask_red=red
	mask_green=green
	mask_blue=blue
End Function

Rem
bbdoc: Get red, green and blue component of current mask color
returns: Red, green and blue values in the range 0..255 
End Rem
Function GetMaskColor( red Var,green Var,blue Var )
	red=color_red
	green=color_green
	blue=color_blue
End Function

Rem
bbdoc: Set drawing viewport
about:
The current ViewPort defines an area within the back buffer that all drawing is clipped to. Any
regions of a DrawCommand that fall outside the current ViewPort are not drawn.
End Rem
Function SetViewport( x,y,width,height )
	viewport_x=x
	viewport_y=y
	viewport_w=width
	viewport_h=height
	blitz2d_driver.SetViewport x,y,width,height
End Function

Rem
bbdoc: Get dimensions of current Viewport.
returns: The horizontal, vertical, width and height values of the current Viewport in the variables supplied.
End Rem
Function GetViewport( x Var,y Var,width Var,height Var )
	x=viewport_x
	y=viewport_y
	width=viewport_w
	height=viewport_h
End Function

Rem
bbdoc: Set drawing origin
about:
The current Origin is an x,y coordinate added to all drawing x,y coordinates after any rotation or scaling.
End Rem
Function SetOrigin( x#,y# )
	origin_x=x
	origin_y=y
End Function

Rem
bbdoc: Get current origin position.
returns: The horizontal and vertical position of the current origin. 
End Rem
Function GetOrigin( x# Var,y# Var )
	x=origin_x
	y=origin_y
End Function

Rem
bbdoc: Set drawing handle
about:
The drawing handle is a 2D offset added to the x,y location of all drawing commands. Unlike #SetOrigin, 
the drawing handle is added before rotation and scale are applied providing a <i>local</i> origin.
end rem
Function SetHandle( x#,y# )
	handle_x=-x
	handle_y=-y
End Function

Rem
bbdoc: Get current drawing handle.
returns: The horizontal and vertical position of the current drawing handle.
End Rem
Function GetHandle( x# Var,y# Var )
	x=handle_x
	y=handle_y
End Function

Rem
bbdoc: Set current rotation
about: @rotation is given in degrees and should be in the range 0 to 360.
End Rem
Function SetRotation( rotation# )
	tform_rot=rotation
	UpdateTransform
End Function

Rem
bbdoc: Get current Max2D rotation setting.
returns: The rotation in degrees.
End Rem
Function GetRotation#()
	Return tform_rot
End Function

Rem
bbdoc: Set current scale
about: @scale_x and @scale_y multiply the width and height of drawing
commands where 0.5 will half the size of the drawing and 2.0 is equivalent 
to doubling the size.
End Rem
Function SetScale( scale_x#,scale_y# )
	tform_scale_x=scale_x
	tform_scale_y=scale_y
	UpdateTransform
End Function

Rem
bbdoc: Get current Max2D scale settings.
returns: The current x and y scale values in the variables supplied. 
End Rem
Function GetScale( scale_x# Var,scale_y# Var )
	scale_x=tform_scale_x
	scale_y=tform_scale_y
End Function

Rem
bbdoc: Set current rotation and scale
about: SetTransform is a shortcut for setting both the rotation and
scale parameters in Max2D with a single function call.
End Rem
Function SetTransform( rotation#=0,scale_x#=1,scale_y#=1 )
	tform_rot=rotation
	tform_scale_x=scale_x
	tform_scale_y=scale_y
	UpdateTransform
End Function

Rem
bbdoc: Make the mouse pointer visible
End Rem
Function ShowMouse()
	blitz2d_driver.SetMouseVisible True
End Function

Rem
bbdoc: Make the mouse pointer invisible
End Rem
Function HideMouse()
	blitz2d_driver.SetMouseVisible False
End Function

Rem
bbdoc: Load an image font
returns: An image font object
end rem
Function LoadImageFont:TImageFont( url:Object,size,style=SMOOTHFONT )
	Return TImageFont.Load( url,size,style )
End Function

Rem
bbdoc: Set current image font
about:
In order to #DrawText in fonts other than the default system font use the #SetImageFont 
command with a font handle returned by the #LoadImageFont command.<br>
<br>
Use <font class=token>SetImageFont Null</font> to select the default, built-in font.
End Rem
Function SetImageFont( font:TImageFont )
	If Not font font=default_font
	image_font=font
End Function

Rem
bbdoc: Get current image font.
returns: The current image font.
End Rem
Function GetImageFont:TImageFont()
	Return image_font
End Function


Rem
bbdoc: Get width of text
about:
This command is useful for calculating horizontal alignment of text when using 
the #DrawText command.
returns:
The width, in pixels, of @text based on the current image font.
End Rem
Function TextWidth( text$ )
	Local width=0
	For Local n=0 Until text.length
		Local c=text[n]-image_font.BaseChar()
		If c<0 Or c>=image_font.CountGlyphs() Continue
		width:+image_font.Glyph(c).Advance()
	Next
	Return width
End Function

Rem
bbdoc: Get height of text
about:
This command is useful for calculating vertical alignment of text when using 
the #DrawText command.
returns:
The width, in pixels, of @text based on the current image font.
End Rem
Function TextHeight( text$ )
	Local height=0
	For Local n=0 Until text.length
		Local c=text[n]-image_font.BaseChar()
		If c<0 Or c>=image_font.CountGlyphs() Continue
		Local x,y,w,h
		image_font.Glyph(c).GetRect( x,y,w,h )
		height=Max(height,h)
	Next
	Return height
End Function

Rem
bbdoc: Load an image
returns: A new image object
about: @url can be either a string or an existing pixmap.<br>
<br>
@flags can be 0, -1, or any combination of:<br>
<br>
<table>
<tr><th>Flags value</th><th>Effect</th></tr>
<tr><td><font class=token>FILTEREDIMAGE</font></td><td>The image is smoothed when scaled or rotated</td></tr>
<tr><td><font class=token>DYNAMICIMAGE</font></td><td>The image can be modified using #LockImage or #GrabImage </td></tr>
<tr><td><font class=token>MASKEDIMAGE</font></td><td>The image is masked with the current mask color</td></tr>
</table><br>
<br>
If flags is -1, the default auto image flags are used: See @AutoImageFlags<br>
<br>
To combine flags, use the <font class=token>|</font> (Boolean OR) operator.
End Rem
Function LoadImage:TImage( url:Object,flags=-1 )
	If flags=-1 flags=auto_imageflags
	Local image:TImage=TImage.Load( url,mask_red,mask_green,mask_blue,flags )
	If Not image Return
	If auto_midhandle MidHandleImage image
	Return image
End Function

Rem
bbdoc: Load a multi-frame image
returns: An image object
about:
#LoadAnimImage extracts multiple image frames from a single, larger image. @url can be either a string or an
existing pixmap.<br>
<br>
See #LoadImage for valid @flags values.
End Rem
Function LoadAnimImage:TImage( url:Object,cell_width,cell_height,first_cell,cell_count,flags=-1 )
	If flags=-1 flags=auto_imageflags
	Local image:TImage=TImage.LoadAnim( url,cell_width,cell_height,first_cell,cell_count,mask_red,mask_green,mask_blue,flags )
	If Not image Return
	If auto_midhandle MidHandleImage image
	Return image
End Function 

Rem
bbdoc: Set an image's handle to an arbitrary point
End Rem
Function SetImageHandle( image:TImage,x#,y# )
	image.handle_x=x
	image.handle_y=y
End Function

Rem
bbdoc: Enable or disable auto midhandle mode
about: When auto midhandle mode is enabled, all images are automatically 'midhandled' (see #MidHandleImage)
when they are created. If auto midhandle mode is disabled, images are handled by their top left corner.
End Rem
Function AutoMidHandle( enable )
	auto_midhandle=enable
End Function

Rem
bbdoc: Set auto image flags
about: The auto image flags are used by #LoadImage when no image flags are specified. See #LoadImage for a
full list of valid image flags.
end rem
Function AutoImageFlags( flags )
	If flags=-1 Return
	auto_imageflags=flags
End Function

Rem
bbdoc: Set an image's handle to its center
End Rem
Function MidHandleImage( image:TImage )
	image.handle_x=image.width*.5
	image.handle_y=image.height*.5
End Function

Rem
bbdoc: Get width of an image
returns: The width, in pixels, of @image
End Rem
Function ImageWidth( image:TImage )
	Return image.width
End Function

Rem
bbdoc: Get height of an image
returns: The height, in pixels, of @image
End Rem
Function ImageHeight( image:TImage )
	Return image.height
End Function

Rem
bbdoc: Create an empty image
returns: A new image object
about: #CreateImage creates an 'empty' image, which should be initialized using either #GrabImage or #LockImage
before being drawn.<br>
<br>
Please refer to #LoadImage for valid @flags values. The @flags value is always combined with DYNAMICIMAGE.
End Rem
Function CreateImage:TImage( width,height,frames=1,flags=-1 )
	If flags=-1 flags=auto_imageflags
	Local image:TImage=TImage.Create( width,height,frames,flags|DYNAMICIMAGE )
	If auto_midhandle MidHandleImage image
	Return image
End Function

Rem
bbdoc: Lock an image for direct access
returns: A pixmap representing the image contents
about: Locking an image allows you to directly access an image's pixels.<br>
<br>
Only images created with the DYNAMICIMAGE flag can be locked.<br>
<br>
Locked images must eventually be unlocked with #UnlockImage before they can be drawn.
end rem
Function LockImage:TPixmap( image:TImage,frame=0,read_lock=True,write_lock=True )
	Return image.frames[frame].Lock( read_lock,write_lock )
End Function

Rem
bbdoc: Unlock an image
about: Unlocks an image previously locked with #LockImage.
end rem
Function UnlockImage( image:TImage,frame=0 )
	image.frames[frame].Unlock
End Function

Rem
bbdoc: Grab an image from the back buffer
about: Copies pixels from the back buffer to an image frame.<br>
<br>
Only images created with the DYNAMICIMAGE flag can be grabbed.
End Rem
Function GrabImage( image:TImage,x,y,frame=0 )
	Local pixmap:TPixmap=blitz2d_driver.GrabPixmap( x,y,image.width,image.height )
	If image.flags&MASKEDIMAGE pixmap=MaskPixmap( pixmap,mask_red,mask_green,mask_blue )
	image.frames[frame]=blitz2d_driver.CreateFrameFromPixmap( pixmap,image.flags )
	image.masks[frame]=pixmap
End Function

Rem
bbdoc: Draw pixmap
end rem
Function DrawPixmap( pixmap:TPixmap,x,y )
	blitz2d_driver.DrawPixmap pixmap,x,y
End Function

Rem
bbdoc: Grab pixmap
end rem
Function GrabPixmap:TPixmap( x,y,width,height )
	Return blitz2d_driver.GrabPixmap( x,y,width,height )
End Function

Const COLLISION_LAYER_ALL=0
Const COLLISION_LAYER_1=$0001
Const COLLISION_LAYER_2=$0002
Const COLLISION_LAYER_3=$0004
Const COLLISION_LAYER_4=$0008
Const COLLISION_LAYER_5=$0010
Const COLLISION_LAYER_6=$0020
Const COLLISION_LAYER_7=$0040
Const COLLISION_LAYER_8=$0080
Const COLLISION_LAYER_9=$0100
Const COLLISION_LAYER_10=$0200
Const COLLISION_LAYER_11=$0400
Const COLLISION_LAYER_12=$0800
Const COLLISION_LAYER_13=$1000
Const COLLISION_LAYER_14=$2000
Const COLLISION_LAYER_15=$4000
Const COLLISION_LAYER_16=$8000
Const COLLISION_LAYER_17=$00010000
Const COLLISION_LAYER_18=$00020000
Const COLLISION_LAYER_19=$00040000
Const COLLISION_LAYER_20=$00080000
Const COLLISION_LAYER_21=$00100000
Const COLLISION_LAYER_22=$00200000
Const COLLISION_LAYER_23=$00400000
Const COLLISION_LAYER_24=$00800000
Const COLLISION_LAYER_25=$01000000
Const COLLISION_LAYER_26=$02000000
Const COLLISION_LAYER_27=$04000000
Const COLLISION_LAYER_28=$08000000
Const COLLISION_LAYER_29=$10000000
Const COLLISION_LAYER_30=$20000000
Const COLLISION_LAYER_31=$40000000
Const COLLISION_LAYER_32=$80000000

Rem
bbdoc: Tests if two images collide
returns: True if any pixels of the two images specified at the given location overlap. 
about: #ImagesCollide uses the current Rotation and Scale factors from the most previous
call to #SetScale and #SetRotation to calculate at a pixel level if the two images collide. 
End Rem
Function ImagesCollide(image1:TImage,x1,y1,frame1,image2:TImage,x2,y2,frame2)
	ResetCollisions COLLISION_LAYER_32
	CollideImage image1,x1,y1,frame1,0,COLLISION_LAYER_32
	If CollideImage(image2,x2,y2,frame2,COLLISION_LAYER_32,0) Return True
End Function

Rem
bbdoc: Tests if two images with arbitrary Rotation and Scales collide
returns: True if any pixels of the two images specified at the given location overlap. 
about: #ImagesCollide2 uses the specified Rotation and Scale paramteters
to calculate at a pixel level if the two images collide (overlap).
End Rem
Function ImagesCollide2(image1:TImage,x1,y1,frame1,rot1#,scalex1#,scaley1#,image2:TImage,x2,y2,frame2,rot2#,scalex2#,scaley2#)
	Local	_scalex#,_scaley#,_rot#,res
	_rot=GetRotation()
	GetScale _scalex,_scaley
	ResetCollisions COLLISION_LAYER_32
	SetRotation rot1
	SetScale scalex1,scaley1
	CollideImage image1,x1,y1,frame1,0,COLLISION_LAYER_32
	SetRotation rot2
	SetScale scalex2,scaley2
	If CollideImage(image2,x2,y2,frame2,COLLISION_LAYER_32,0) res=True
	SetRotation _rot
	SetScale _scalex,_scaley
	Return res
End Function

Rem
bbdoc: Clears collision layers specified by the value of @mask, mask=0 for all layers. 
about: The BlitzMax 2D collision system manages 32 layers, the @mask parameter can
be a combination of the following values or the special value COLLISION_LAYER_ALL in order 
to perform collision operations on multiple layers.<br>
Note: @COLLISION_LAYER_32 is used by the ImagesCollide and ImagesCollide2 commands.
<table>
<tr><th>Layer</th><th>MaskValue</th></tr>
<tr><td>COLLISION_LAYER_ALL</td><td>0</td></tr>
<tr><td>COLLISION_LAYER_1</td><td>$0001</td></tr>
<tr><td>COLLISION_LAYER_2</td><td>$0002</td></tr>
<tr><td>COLLISION_LAYER_3</td><td>$0004</td></tr>
<tr><td>COLLISION_LAYER_4</td><td>$0008</td></tr>
<tr><td>COLLISION_LAYER_5</td><td>$0010</td></tr>
<tr><td>COLLISION_LAYER_6</td><td>$0020</td></tr>
<tr><td>COLLISION_LAYER_7</td><td>$0040</td></tr>
<tr><td>COLLISION_LAYER_8</td><td>$0080</td></tr>
<tr><td>COLLISION_LAYER_9</td><td>$0100</td></tr>
<tr><td>COLLISION_LAYER_10</td><td>$0200</td></tr>
<tr><td>COLLISION_LAYER_11</td><td>$0400</td></tr>
<tr><td>COLLISION_LAYER_12</td><td>$0800</td></tr>
<tr><td>COLLISION_LAYER_13</td><td>$1000</td></tr>
<tr><td>COLLISION_LAYER_14</td><td>$2000</td></tr>
<tr><td>COLLISION_LAYER_15</td><td>$4000</td></tr>
<tr><td>COLLISION_LAYER_16</td><td>$8000</td></tr>
</table>
EndRem
Function ResetCollisions(mask%=0)
	Local	i,q:TQuad
	For i=0 To 31
		If mask=0 Or mask&(1 Shl i)
			q=quadlayer[i]
			If q
				While q.link
					q=q.link
				Wend
				q.link=freequads				
				q=quadlayer[i]
				freequads=q
				quadlayer[i]=Null
			EndIf
		EndIf
	Next
End Function

Rem 
bbdoc: Pixel accurate collision testing between transformed Images. 
about: The @collidemask specifies any layers to test for collision with. 
The @writemask specifies which if any collision layers the @image is added to in it's currently transformed state. 
The id specifies an object to be returned to future #CollideImage calls when collisions occur. 
EndRem
Function CollideImage:Object[](image:TImage,x,y,frame,collidemask%,writemask%,id:Object=Null) 
	Local	q:TQuad
	q=CreateQuad(image,frame,x,y,image.width,image.height,id)
	Return CollideQuad(q,collidemask,writemask)
End Function

Rem
bbdoc: Pixel accurate collision testing between image layers 
about: The @collidemask specifies any layers to test for collision with.<br>
The @writemask specifies which if any collision layers the @image is added to in it's currently transformed state.<br> 
The @id specifies an object to be returned to future #CollideImage calls when collisions occur.<br>
EndRem
Function CollideRect:Object[](x,y,w,h,collidemask%,writemask%,id:Object=Null) 
	Local	q:TQuad
	q=CreateQuad(Null,0,x,y,w,h,id)
	Return CollideQuad(q,collidemask,writemask)
End Function

Private

Global	cix#,ciy#,cjx#,cjy#

Function SetCollisions2DTransform(ix#,iy#,jx#,jy#)	'callback from module Blitz2D
	cix=ix
	ciy=iy
	cjx=jx
	cjy=jy
End Function

Global TextureMaps:TPixmap[]
Global LineBuffer[]
Global	quadlayer:TQuad[32]
Global	freequads:TQuad

Const POLYX=0
Const POLYY=1
Const POLYU=2
Const POLYV=3

Function DotProduct(x0#,y0#,x1#,y1#,x2#,y2#)
	Return (((x2-x1)*(y1-y0))-((x1-x0)*(y2-y1)))
End Function

Function ClockwisePoly(data#[],channels)	'flips order if anticlockwise
	Local	count,clk,i,j
	Local	r0,r1,r2
	Local	t#
	
	count=Len(data)/channels
' clock wise test
	r0=0
	r1=channels
	clk=2
	For i=2 To count-1
		r2=r1+channels
		If DotProduct(data[r0+POLYX],data[r0+POLYY],data[r1+POLYX],data[r1+POLYY],data[r2+POLYX],data[r2+POLYY])>=0 clk:+1	
		r1=r2
	Next
	If clk<count Return
' flip order for anti@#!*wise
	r0=0
	r1=(count-1)*channels
	While r0<r1
		For j=0 To channels-1
			t=data[r0+j]
			data[r0+j]=data[r1+j]
			data[r1+j]=t
		Next
		r0:+channels
		r1:-channels
	Wend
End Function

Type rpoly 'Extends TNode
	Field	texture:TPixmap
	Field	data#[]
	Field	channels,count,size
	Field	ldat#[],ladd#[]
	Field	rdat#[],radd#[]
	Field	Left,Right,top
	Field	state
End Type

Function RenderPolys(vdata#[][],channels[],textures:TPixmap[],renderspans(polys:TList,count,ypos))
	Local	polys:rpoly[],p:rpoly,pcount
	Local	active:TList
	Local	top,bot
	Local	n,y,h,i,j,res
	Local	data#[]

	bot=$80000000
	top=$7fffffff
	n=Len(vdata)
' create polys an array of poly renderers	
	polys=New rpoly[n]		
	For i=0 Until n
		p=New rpoly
		polys[i]=p
		p.texture=textures[i]
		p.data=vdata[i]
		p.channels=channels[i]
		p.count=Len(p.data)/p.channels
		p.size=p.count*p.channels
		ClockwisePoly(p.data,p.channels)	'flips order if anticlockwise
' find top verticies
		p.Left=0
		j=0
		p.top=$7fffffff
		While j<p.size
			y=p.data[j+POLYY]		'float to int conversion
			If y<p.top p.top=y;p.Left=j
			If y<top top=y
			If y>bot bot=y
			j:+p.channels
		Wend
		p.Right=p.Left
	Next
	active=New TList
	pcount=0
' draw top to bottom
	For y=top To bot-1
' get left gradient
		For p=EachIn polys			
			If p.state=2 Continue 
			If p.state=0 And y<p.top Continue
			data=p.data
			If y>=Int(data[p.Left+POLYY])
				j=p.Left
				i=(p.Left-p.channels)
				If i<0 i:+p.size
				While i<>p.Left
					If Int(data[i+POLYY])>y Exit
					j=i
					i=(i-p.channels)
					If i<0 i:+p.size
				Wend
				h=Int(data[i+POLYY])-Int(data[j+POLYY])
				If i=p.Left Or h<=0
					active.remove p
'					p.remove
					pcount:-1
					p.state=2
					Continue
				EndIf
				p.ldat=data[j..j+p.channels]
				p.ladd=data[i..i+p.channels]				
				For j=0 To p.channels-1
					p.ladd[j]=(p.ladd[j]-p.ldat[j])/h
					p.ldat[j]:+p.ladd[j]*0.5
				Next
				p.Left=i			
				If p.state=0
					p.state=1
					active.AddLast p
					pcount:+1
				EndIf			
			EndIf
' get right gradient
			If y>=Int(data[p.Right+POLYY])
				i=(p.Right+p.channels) Mod p.size
				j=p.Right
				While i<>p.Right
					If Int(data[i+POLYY])>y Exit
					j=i
					i=(i+p.channels)Mod p.size
				Wend
				h=Int(data[i+POLYY])-Int(data[j+POLYY])
				If i=p.Right Or h<=0
					active.remove p
					pcount:-1
					p.state=2
					Continue
				EndIf
				p.rdat=data[j..j+p.channels]
				p.radd=data[i..i+p.channels]
				For j=0 To p.channels-1
					p.radd[j]=(p.radd[j]-p.rdat[j])/h
					p.rdat[j]:+p.radd[j]*0.5
				Next
				p.Right=i
				If p.state=0
					p.state=1
					active.AddLast p
					pcount:+1
				EndIf			
			EndIf
		Next	
' call renderer
		If pcount
			res=renderspans(active,pcount,y)
			If res<0 Return res
		EndIf
' increment spans
		For p=EachIn active
			For j=0 To p.channels-1
				p.ldat[j]:+p.ladd[j]
				p.rdat[j]:+p.radd[j]
			Next
		Next
	Next
	Return res
End Function

Function CollideSpans(polys:TList,count,y)
	Local	p:rpoly
	Local	startx,endx
	Local	x0,x1,w,x
	Local	u#,v#,ui#,vi#
	Local	pix Ptr
	Local	src:TPixmap
	Local	tw,th,tp,argb
	Local	width,skip#
	

	startx=$7fffffff
	endx=$80000000
	If count<2 Return 0
	p=rpoly(polys.ValueAtIndex(0))
	startx=p.ldat[POLYX]
	endx=p.rdat[POLYX]
	p=rpoly(polys.ValueAtIndex(1))
	x0=p.ldat[POLYX]
	x1=p.rdat[POLYX]
	If x0>=endx Return 0
	If x1<=startx Return 0
	If x0>startx startx=x0
	If x1<endx endx=x1
	width=endx-startx
	If width<=0 Return 0
	If width>Len(LineBuffer) LineBuffer=New Int[width]
	MemClear LineBuffer,width*4
	For p=EachIn polys
		src=p.texture
		If src
			x0=p.ldat[POLYX]
			x1=p.rdat[POLYX]
			w=x1-x0
			If w<=0 Continue		
			u=p.ldat[POLYU]
			v=p.ldat[POLYV]
			ui=(p.rdat[POLYU]-u)/w
			vi=(p.rdat[POLYV]-v)/w
			skip=(startx-x0)+0.5
			u=u+ui*skip
			v=v+vi*skip			
			pix=Int Ptr(src.pixels)
			tw=src.width
			th=src.height
			tp=src.pitch/4
			For x=0 Until width
				If u<0.0 u=0.0
				If v<0.0 v=0.0
				If u>1.0 u=1.0
				If v>1.0 v=1.0
?BigEndian
				argb=$00000080 & pix[(Int(v*th))*tp+(Int(u*tw))]
?LittleEndian
				argb=$80000000 & pix[(Int(v*th))*tp+(Int(u*tw))]
?
				If (argb)
					If LineBuffer[x] Return -1
					LineBuffer[x]=argb
				EndIf
				u:+ui
				v:+vi
			Next
		Else
			For x=0 Until width
				If LineBuffer[x] Return -1
				LineBuffer[x]=-1
			Next
		EndIf
	Next
	Return 0
End Function

Type TQuad
	Field	link:TQuad
	Field	id:Object
	Field	mask:TPixmap
	Field	frame	
	Field	minx#,miny#,maxx#,maxy#
	Field	xyuv#[16]
		
	Method SetCoords(tx0#,ty0#,tx1#,ty1#,tx2#,ty2#,tx3#,ty3#)
		xyuv[0]=tx0
		xyuv[1]=ty0
		xyuv[2]=0.0
		xyuv[3]=0.0		
		xyuv[4]=tx1
		xyuv[5]=ty1
		xyuv[6]=1.0
		xyuv[7]=0.0				
		xyuv[8]=tx2
		xyuv[9]=ty2
		xyuv[10]=1.0
		xyuv[11]=1.0		
		xyuv[12]=tx3
		xyuv[13]=ty3
		xyuv[14]=0.0
		xyuv[15]=1.0
		minx=tx0
		miny=ty0
		maxx=tx0
		maxy=ty0
		If tx1<minx minx=tx1
		If ty1<miny miny=ty1
		If tx1>maxx maxx=tx1
		If ty1>maxy maxy=ty1
		If tx2<minx minx=tx2
		If ty2<miny miny=ty2
		If tx2>maxx maxx=tx2
		If ty2>maxy maxy=ty2
		If tx3<minx minx=tx3
		If ty3<miny miny=ty3
		If tx3>maxx maxx=tx3
		If ty3>maxy maxy=ty3			
	End Method
End Type

Function QuadsCollide(p:TQuad,q:TQuad)
	Local	vertlist#[][2]
	Local	textures:TPixmap[2]
	Local	channels[2]
	
	If p.maxx<q.minx Or p.maxy<q.miny Or p.minx>q.maxx Or p.miny>q.maxy Return False
	vertlist[0]=p.xyuv	
	vertlist[1]=q.xyuv	
	textures[0]=p.mask
	textures[1]=q.mask
	channels[0]=4
	channels[1]=4
	Return RenderPolys(vertlist,channels,textures,CollideSpans)
End Function

Function CreateQuad:TQuad(image:TImage,frame,x#,y#,w#,h#,id:Object)
	Local	x0#,y0#,x1#,y1#,tx#,ty#
	Local	tx0#,ty0#,tx1#,ty1#,tx2#,ty2#,tx3#,ty3#
	Local	minx#,miny#,maxx#,maxy#
	Local	q:TQuad
	Local	f:TImageFrame

	If image
		x0=-image.handle_x
		y0=-image.handle_y
	EndIf
	x1=x0+w
	y1=y0+h
	tx=x+origin_x
	ty=y+origin_y
	tx0=x0*cix+y0*ciy+tx
	ty0=x0*cjx+y0*cjy+ty
	tx1=x1*cix+y0*ciy+tx
	ty1=x1*cjx+y0*cjy+ty
	tx2=x1*cix+y1*ciy+tx
	ty2=x1*cjx+y1*cjy+ty
	tx3=x0*cix+y1*ciy+tx
	ty3=x0*cjx+y1*cjy+ty
	If freequads
		q=freequads
		freequads=q.link
	Else
		q=New TQuad
	EndIf
	q.link=Null
	q.id=id
	If image
		q.mask=image.masks[frame]
		f=image.frames[frame]
	EndIf
	q.setcoords(tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3)	
	Return q
End Function

Function CollideQuad:Object[](pquad:TQuad,collidemask%,writemask%) 
	Local	result:Object[]
	Local	p:TQuad,q:TQuad
	Local	i,j,count

	p=pquad				'CreateImageQuad(image,frame,x,y)
' check for collisions
	For i=0 To 31
		If collidemask & (1 Shl i)
			q=quadlayer[i]
			While q
				If QuadsCollide(p,q)
					If count=Len(result) result=result[..((count+4)*1.2)]
					result[count]=q.id
					count:+1
				EndIf				
				q=q.link
			Wend		
		EndIf
	Next
' write to layers	
	For i=0 To 31
		If writemask & (1 Shl i)
			If freequads
				q=freequads
				freequads=q.link
			Else
				q=New TQuad
			EndIf
			q.id=p.id;	'TODO:optimize with memcpy?
			q.mask=p.mask;
			q.frame=p.frame
			MemCopy q.xyuv,p.xyuv,64
			q.minx=p.minx;q.miny=p.miny;q.maxx=p.maxx;q.maxy=p.maxy;
			q.link=quadlayer[i]
			quadlayer[i]=q
		EndIf
	Next
' return result
	Return result[..count]
End Function



thanks a lot, it helps me very much!!

After the last call to SyncMods I've seen the "AppTitle$"-Variable in the brl.blitz-mod.
This is exactly what I was asking for.
Thanks a lot, Mark!