Explorar el Código

odd.mod. Initial Import.

woollybah hace 9 años
padre
commit
c6a08eb366
Se han modificado 4 ficheros con 794 adiciones y 0 borrados
  1. 6 0
      .gitignore
  2. 161 0
      d3d9odd2d.mod/d3d9odd2d.bmx
  3. 144 0
      glodd2d.mod/glodd2d.bmx
  4. 483 0
      odd2d.mod/odd2d.bmx

+ 6 - 0
.gitignore

@@ -0,0 +1,6 @@
+.bmx
+*.x64.a
+*.x64.i
+*.x86.a
+*.x86.i
+*.bak

+ 161 - 0
d3d9odd2d.mod/d3d9odd2d.bmx

@@ -0,0 +1,161 @@
+Strict
+
+Rem
+bbdoc: Graphics/Direct3D9 Odd2D
+about:
+The Direct3D9 Odd2D module provides an Direct3D9 driver for #Odd2D.
+End Rem
+Module ODD.D3D9Odd2D
+
+ModuleInfo "Version: 1.03"
+ModuleInfo "Author: David Williamson"
+ModuleInfo "License: Public Domain"
+
+?Win32
+
+Import ODD.Odd2D
+Import BRL.D3D9Max2D
+
+Private
+
+Global _driver:TD3D9Odd2DDriver
+
+Public
+
+Type TOD3D9ImageFrame Extends TImageFrame
+	Field d3d9if:TD3D9ImageFrame
+	
+	Method Draw( x0#,y0#,x1#,y1#,tx#,ty#,sx#,sy#,sw#,sh# )
+		Local rot:Float=GetRotation()
+		Local sclx:Float,scly:Float
+		GetScale sclx,scly
+		SetRotation rot-_odd2dDriver.tform_scr_rot
+		SetScale sclx*_odd2dDriver.tform_scr_zoom,scly*_odd2dDriver.tform_scr_zoom
+		_odd2dDriver.TransformPoint tx,ty
+		tx:+_odd2dDriver.focus_x+_odd2dDriver.border_x
+		ty:+_odd2dDriver.focus_y+_odd2dDriver.border_y
+		
+		d3d9if.Draw x0,y0,x1,y1,tx,ty,sx,sy,sw,sh
+		
+		SetRotation rot
+		SetScale sclx,scly
+	End Method
+	
+	Method DrawPoly( xyuv:Float[], handlex:Float, handley:Float, tx:Float, ty:Float )
+		If xyuv.length<12 Or (xyuv.length Mod 4<>0) Return
+		Local segs:Int=xyuv.length/4
+		Local vrts#[]=New Float[segs*6]	
+		Local x:Float, y:Float, u:Float, v:Float
+		Local colour:Int=(Int(255*_driver.m2d_alpha) Shl 24)|(_driver.m2d_red Shl 16)|(_driver.m2d_green Shl 8)|_driver.m2d_blue
+		Local c:Int Ptr=Int Ptr(Float Ptr(vrts))
+		For Local i:Int=0 Until segs
+			x=xyuv[i*4+0]-handlex
+			y=xyuv[i*4+1]-handley
+			u=xyuv[i*4+2]*d3d9if._uscale
+			v=xyuv[i*4+3]*d3d9if._vscale
+			
+			vrts[i*6+0]=x*_driver.m2d_ix+y*_driver.m2d_iy+tx
+			vrts[i*6+1]=x*_driver.m2d_jx+y*_driver.m2d_jy+ty
+			c[i*6+3]=colour
+			vrts[i*6+4]=u
+			vrts[i*6+5]=v
+		Next
+		
+		d3d9if.Draw 0,0,0,0,0,0,0,0,0,0	'KLUDGE - Note to Mr. Sibly an EnableTex function
+		
+		_driver._d3dDev.DrawPrimitiveUP D3DPT_TRIANGLEFAN,segs-2,vrts,24
+	End Method
+		
+	Function CreateFromPixmap:TOD3D9ImageFrame( pixmap:TPixmap,flags:Int )
+		Local frame:TOD3D9ImageFrame=New TOD3D9ImageFrame
+		frame.d3d9if:TD3D9ImageFrame=TD3D9ImageFrame(D3D9Max2DDriver().CreateFrameFromPixmap(pixmap,flags))
+		Return frame
+	End Function
+	
+End Type
+
+Type TD3D9Odd2DDriver Extends TOdd2DDriver
+	Field _d3dDev:IDirect3DDevice9
+	
+	Method Create:TD3D9Odd2DDriver()
+		_m2ddriver=D3D9Max2DDriver()
+		
+		InitFields
+		
+		If Not _m2ddriver Then Return Null Else Return Self
+	End Method
+	
+'	Method GraphicsModes:TGraphicsMode[]() Abstract
+	
+	Method AttachGraphics:TMax2DGraphics( widget:Byte Ptr, flags:Int )
+		Local g:TD3D9Graphics=D3D9GraphicsDriver().AttachGraphics( widget,flags )
+		If g Return TMax2DGraphics.Create( g,Self )
+	End Method
+	
+	Method CreateGraphics:TGraphics( width:Int, height:Int ,depth:Int, hertz:Int, flags:Int )
+		Local g:TD3D9Graphics=D3D9GraphicsDriver().CreateGraphics( width,height,depth,hertz,flags )
+		If g Return TMax2DGraphics.Create( g,Self )
+	End Method
+	
+	Method SetGraphics( g:TGraphics )
+		Super.SetGraphics g
+		If g Then _d3dDev=TD3D9Graphics(TMax2DGraphics(g)._graphics).GetDirect3DDevice()
+	End Method
+	
+'	Method Flip( sync ) Abstract
+	
+	Method CreateFrameFromPixmap:TOD3D9ImageFrame( pixmap:TPixmap, flags:Int )
+		Return TOD3D9ImageFrame.CreateFromPixmap(pixmap,flags)
+	End Method
+	
+	Method SetBlend( blend:Int )
+		Super.SetBlend blend
+		Select m2d_blend
+		Case MOD2XBLEND
+			_d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,False
+			_d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,True
+			_d3dDev.SetRenderState D3DRS_SRCBLEND,D3DBLEND_DESTCOLOR
+			_d3dDev.SetRenderState D3DRS_DESTBLEND,D3DBLEND_SRCCOLOR
+		End Select
+	End Method
+	
+'	Method SetAlpha( alpha# ) Abstract
+'	Method SetColor( red,green,blue ) Abstract
+'	Method SetClsColor( red,green,blue ) Abstract
+'	Method SetViewport( x,y,width,height ) Abstract
+'	Method SetTransform( xx#,xy#,yx#,yy# ) Abstract
+'	Method SetLineWidth( width# ) Abstract
+	
+'	Method Cls() Abstract
+'	Method Plot( x#,y# ) Abstract
+'	Method DrawLine( x0#,y0#,x1#,y1#,tx#,ty# ) Abstract
+'	Method DrawRect( x0#,y0#,x1#,y1#,tx#,ty# ) Abstract
+'	Method DrawOval( x0#,y0#,x1#,y1#,tx#,ty# ) Abstract
+'	Method DrawPoly( xy#[],handlex#,handley#,originx#,originy# ) Abstract
+		
+'	Method DrawPixmap( pixmap:TPixmap,x,y ) Abstract
+'	Method GrabPixmap:TPixmap( x,y,width,height ) Abstract
+	
+'	Method SetResolution( width#,height# ) Abstract
+
+	Method DrawPolyImage( xyuv#[],iframe:TImageFrame,handlex#,handley#,originx#,originy# )
+		TOD3D9ImageFrame(iframe).DrawPoly xyuv,handlex,handley,originx,originy
+	End Method
+
+End Type
+
+Rem
+bbdoc: Get Direct3D9 Odd2D Driver
+about:
+The returned driver can be used with #SetGraphicsDriver to enable Direct3D9 Odd2D 
+rendering.
+End Rem
+Function D3D9Odd2DDriver:TD3D9Odd2DDriver()
+	If Not _driver Then
+		_driver=New TD3D9Odd2DDriver.Create()
+	EndIf
+	Return _driver
+End Function
+
+?
+

+ 144 - 0
glodd2d.mod/glodd2d.bmx

@@ -0,0 +1,144 @@
+Strict
+
+Rem
+bbdoc: Graphics/OpenGL Odd2D
+about:
+The OpenGL Odd2D module provides an OpenGL driver for #Odd2D.
+End Rem
+Module ODD.GLOdd2D
+
+ModuleInfo "Version: 1.03"
+ModuleInfo "Author: David Williamson"
+ModuleInfo "License: Public Domain"
+
+Import ODD.Odd2D
+Import BRL.GLMax2D
+
+Private
+
+Global _driver:TGLOdd2DDriver
+
+Public
+
+Type TOGLImageFrame Extends TImageFrame
+	Field glif:TGLImageFrame
+	
+	Method Draw( x0#,y0#,x1#,y1#,tx#,ty#,sx#,sy#,sw#,sh# )
+		Local rot:Float=GetRotation()
+		Local sclx:Float,scly:Float
+		GetScale sclx,scly
+		SetRotation rot-_odd2dDriver.tform_scr_rot
+		SetScale sclx*_odd2dDriver.tform_scr_zoom,scly*_odd2dDriver.tform_scr_zoom
+		_odd2dDriver.TransformPoint tx,ty
+		tx:+_odd2dDriver.focus_x+_odd2dDriver.border_x
+		ty:+_odd2dDriver.focus_y+_odd2dDriver.border_y
+		
+		glif.Draw x0,y0,x1,y1,tx,ty,sx,sy,sw,sh
+		
+		SetRotation rot
+		SetScale sclx,scly
+	End Method
+	
+	Method DrawPoly( xyuv:Float[],handle_x:Float,handle_y:Float,origin_x:Float,origin_y:Float )
+		If xyuv.length<12 Or (xyuv.length Mod 4<>0) Return
+		
+		Local x:Float, y:Float, u:Float, v:Float
+		
+		glif.Draw 0,0,0,0,0,0,0,0,0,0	'KLUDGE - Note to Mr. Sibly please make EnableTex public
+		glBegin GL_POLYGON
+		For Local i:Int=0 Until xyuv.length Step 4
+			x=xyuv[i+0]-handle_x
+			y=xyuv[i+1]-handle_y
+			u=xyuv[i+2]*glif.uscale
+			v=xyuv[i+3]*glif.vscale
+			
+			glTexCoord2f u,v
+			glVertex2f x*_driver.m2d_ix+y*_driver.m2d_iy+origin_x,x*_driver.m2d_jx+y*_driver.m2d_jy+origin_y
+		Next
+		glEnd
+	End Method
+		
+	Function CreateFromPixmap:TOGLImageFrame( pixmap:TPixmap,flags:Int )
+		Local frame:TOGLImageFrame=New TOGLImageFrame
+		frame.glif=TGLImageFrame(GLMax2DDriver().CreateFrameFromPixmap(pixmap,flags))
+		Return frame
+	End Function
+End Type
+
+Type TGLOdd2DDriver Extends TOdd2DDriver
+	
+	Method Create:TGLOdd2DDriver()
+		_m2ddriver=GLMax2DDriver()
+		
+		InitFields
+		
+		If Not _m2ddriver Then Return Null Else Return Self
+	End Method
+	
+'	Method GraphicsModes:TGraphicsMode[]() Abstract
+	
+	Method AttachGraphics:TMax2DGraphics( widget:Byte Ptr, flags:Int )
+		Local g:TGLGraphics=GLGraphicsDriver().AttachGraphics( widget,flags )
+		If g Return TMax2DGraphics.Create( g,Self )
+	End Method
+	
+	Method CreateGraphics:TGraphics( width:Int, height:Int ,depth:Int, hertz:Int, flags:Int )
+		Local g:TGLGraphics=GLGraphicsDriver().CreateGraphics( width,height,depth,hertz,flags )
+		If g Return TMax2DGraphics.Create( g,Self )
+	End Method
+	
+'	Method SetGraphics( g:TGraphics ) Abstract
+	
+'	Method Flip( sync ) Abstract
+	
+	Method CreateFrameFromPixmap:TOGLImageFrame( pixmap:TPixmap, flags:Int )
+		Return TOGLImageFrame.CreateFromPixmap(pixmap,flags)
+	End Method
+	
+	Method SetBlend( blend:Int )
+		Super.SetBlend blend
+		Select m2d_blend
+		Case MOD2XBLEND
+			glEnable GL_BLEND
+			glBlendFunc GL_DST_COLOR,GL_SRC_COLOR
+			glDisable GL_ALPHA_TEST
+		End Select
+	End Method
+	
+'	Method SetAlpha( alpha# ) Abstract
+'	Method SetColor( red,green,blue ) Abstract
+'	Method SetClsColor( red,green,blue ) Abstract
+'	Method SetViewport( x,y,width,height ) Abstract
+'	Method SetTransform( xx#,xy#,yx#,yy# ) Abstract
+'	Method SetLineWidth( width# ) Abstract
+	
+'	Method Cls() Abstract
+'	Method Plot( x#,y# ) Abstract
+'	Method DrawLine( x0#,y0#,x1#,y1#,tx#,ty# ) Abstract
+'	Method DrawRect( x0#,y0#,x1#,y1#,tx#,ty# ) Abstract
+'	Method DrawOval( x0#,y0#,x1#,y1#,tx#,ty# ) Abstract
+'	Method DrawPoly( xy#[],handlex#,handley#,originx#,originy# ) Abstract
+		
+'	Method DrawPixmap( pixmap:TPixmap,x,y ) Abstract
+'	Method GrabPixmap:TPixmap( x,y,width,height ) Abstract
+	
+'	Method SetResolution( width#,height# ) Abstract
+
+	Method DrawPolyImage( xyuv#[],iframe:TImageFrame,handlex#,handley#,originx#,originy# )
+		TOGLImageFrame(iframe).DrawPoly xyuv,handlex,handley,originx,originy
+	End Method
+
+End Type
+
+Rem
+bbdoc: Get OpenGL Odd2D Driver
+about:
+The returned driver can be used with #SetGraphicsDriver to enable OpenGL Odd2D 
+rendering.
+End Rem
+Function GLOdd2DDriver:TGLOdd2DDriver()
+	If Not _driver Then
+		_driver=New TGLOdd2DDriver.Create()
+	EndIf
+	Return _driver
+End Function

+ 483 - 0
odd2d.mod/odd2d.bmx

@@ -0,0 +1,483 @@
+Strict
+
+Rem
+bbdoc: Graphics/Odd2D
+about:
+All Max2D commands should work as intended with the Odd2D module.
+End Rem
+Module ODD.Odd2D
+
+ModuleInfo "Version: 1.03"
+ModuleInfo "Author: David Williamson"
+ModuleInfo "License: Public Domain"
+
+Import BRL.Max2D
+
+'Const BORDER_KEEP:Int=1
+Const BORDER_NONE:Int=0
+Const BORDER_LETTERBOX_FILL:Int=2
+Const BORDER_LETTERBOX_SOLID:Int=3
+Const BORDER_BESTFIT_FILL:Int=4
+Const BORDER_BESTFIT_SOLID:Int=5
+
+Rem
+bbdoc: Modulate 2x blend mode
+about: Can be used with #SetBlend for mudulate 2x blending.
+End Rem
+Const MOD2XBLEND:Int=6
+
+Global _odd2dDriver:TOdd2DDriver
+
+Type TOdd2DDriver Extends TMax2DDriver
+	Field _m2ddriver:TMax2DDriver
+	
+	Field border_red:Int, border_green:Int, border_blue:Int
+	Field border_mode:Int, border_x:Float, border_y:Float
+	Field full_width:Float, full_height:Float, virt_width:Float, virt_height:Float, ratio:Float
+	
+	Field tform_scr_rot:Float, tform_scr_zoom:Float
+	Field tform_scr_ix#,tform_scr_iy#,tform_scr_jx#,tform_scr_jy#
+	
+	Field focus_x:Float, focus_y:Float
+	
+	Field adj_vp_x:Int, adj_vp_y:Int, adj_vp_width:Int, adj_vp_height:Int
+	
+	Field m2d_blend:Int, m2d_alpha:Float, m2d_linewidth:Float
+	Field m2d_clsred:Int, m2d_clsgreen:Int, m2d_clsblue:Int
+	Field m2d_red:Int, m2d_green:Int, m2d_blue:Int
+	Field m2d_ix:Float, m2d_iy:Float, m2d_jx:Float, m2d_jy:Float
+	
+	Method GraphicsModes:TGraphicsMode[]()
+		Return _m2ddriver.GraphicsModes()
+	End Method
+	
+'	Method AttachGraphics:TGraphics( widget,flags ) Abstract
+	
+'	Method CreateGraphics:TGraphics( width,height,depth,hertz,flags ) Abstract
+	
+	Method SetGraphics( g:TGraphics )
+		_m2ddriver.SetGraphics g
+		
+		_odd2dDriver=TOdd2DDriver(_max2dDriver)
+	End Method
+	
+	Method Flip( sync:Int )
+		ClearBorder
+		_m2ddriver.Flip sync
+	End Method
+	
+'	Method CreateFrameFromPixmap:TImageFrame( pixmap:TPixmap,flags ) Abstract
+	
+	Method SetBlend( blend:Int )
+		m2d_blend=blend
+		_m2dDriver.SetBlend blend
+	End Method
+	
+	Method SetAlpha( alpha:Float )
+		m2d_alpha=alpha
+		_m2dDriver.SetAlpha alpha
+	End Method
+	
+	Method SetColor( red:Int, green:Int, blue:Int )
+		m2d_red=red;m2d_green=green;m2d_blue=blue
+		_m2dDriver.SetColor red,green,blue
+	End Method
+	
+	Method SetClsColor( red:Int, green:Int, blue:Int )
+		m2d_clsred=red;m2d_clsgreen=green;m2d_clsblue=blue
+		_m2dDriver.SetClsColor red,green,blue
+	End Method
+	
+	Method SetViewport( x:Int, y:Int, width:Int, height:Int )
+		Local xscale:Float=full_width/virt_width
+		Local yscale:Float=full_height/virt_height
+		adj_vp_x=border_x*ratio+x/xscale
+		adj_vp_y=border_y*ratio+y/yscale
+		adj_vp_width=width/xscale
+		adj_vp_height=height/yscale
+		_m2dDriver.SetViewport adj_vp_x,adj_vp_y,adj_vp_width,adj_vp_height
+	End Method
+	
+	Method SetTransform( xx:Float, xy:Float, yx:Float, yy:Float )
+		m2d_ix=xx;m2d_iy=xy;m2d_jx=yx;m2d_jy=yy
+		_m2dDriver.SetTransform xx,xy,yx,yy
+	End Method
+	
+	Method SetLineWidth( width:Float )
+		m2d_linewidth=width
+		_m2dDriver.SetLineWidth width
+	End Method
+	
+	Method Cls()
+		_m2dDriver.Cls
+	End Method
+	
+	Method Plot( x#,y# )
+		TransformPoint x,y
+		x:+border_x+focus_x
+		y:+border_y+focus_y
+		
+		_m2dDriver.Plot x,y
+	End Method
+	
+	Method DrawLine( x0#,y0#,x1#,y1#,tx#,ty# )
+		TransformPoint x0,y0
+		TransformPoint x1,y1
+		TransformPoint tx,ty
+		tx:+border_x+focus_x
+		ty:+border_y+focus_y
+		
+		_m2dDriver.DrawLine x0,y0,x1,y1,tx,ty
+	End Method
+	
+	Method DrawRect( x0#,y0#,x1#,y1#,tx#,ty# )
+		Local rot:Float=GetRotation()
+		Local sclx:Float,scly:Float
+		GetScale sclx,scly
+		SetRotation rot-tform_scr_rot
+		SetScale sclx*tform_scr_zoom,scly*tform_scr_zoom
+		TransformPoint tx,ty
+		tx:+focus_x+border_x
+		ty:+focus_y+border_y
+		
+		_m2dDriver.DrawRect x0,y0,x1,y1,tx,ty
+		
+		SetRotation rot
+		SetScale sclx,scly
+	End Method
+	
+	Method DrawOval( x0#,y0#,x1#,y1#,tx#,ty# )
+		Local rot:Float=GetRotation()
+		Local sclx:Float,scly:Float
+		GetScale sclx,scly
+		SetRotation rot-tform_scr_rot
+		SetScale sclx*tform_scr_zoom,scly*tform_scr_zoom
+		TransformPoint tx,ty
+		tx:+focus_x+border_x
+		ty:+focus_y+border_y
+		
+		_m2dDriver.DrawOval x0,y0,x1,y1,tx,ty
+		
+		SetRotation rot
+		SetScale sclx,scly
+	End Method
+	
+	Method DrawPoly( xy#[],handlex#,handley#,originx#,originy# )
+		Local rot:Float=GetRotation()
+		Local sclx:Float,scly:Float
+		GetScale sclx,scly
+		SetRotation rot-tform_scr_rot
+		SetScale sclx*tform_scr_zoom,scly*tform_scr_zoom
+		TransformPoint originx,originy
+		originx:+focus_x+border_x
+		originy:+focus_y+border_y
+		
+		_m2dDriver.DrawPoly xy,handlex,handley,originx,originy
+		
+		SetRotation rot
+		SetScale sclx,scly
+	End Method
+	
+	Method DrawPixmap( pixmap:TPixmap, x:Int, y:Int )
+		_m2dDriver.DrawPixmap pixmap,x,y
+	End Method
+	
+	Method GrabPixmap:TPixmap( x:Int, y:Int, width:Int, height:Int )
+		Return _m2dDriver.GrabPixmap(x,y,width,height)
+	End Method
+	
+	Method SetResolution( width#,height# )
+		virt_width=width;virt_height=height
+		Local gwidth:Int=GraphicsWidth()
+		Local gheight:Int=GraphicsHeight()
+		If border_mode=BORDER_NONE
+			border_x=0;border_y=0;full_width=virt_width;full_height=virt_height;ratio=1
+			adj_vp_x=0;adj_vp_y=0;adj_vp_width=Ceil(gwidth);adj_vp_height=Ceil(gheight)
+			_m2dDriver.SetResolution(full_width,full_height)
+			_m2dDriver.SetViewport adj_vp_x,adj_vp_y,adj_vp_width,adj_vp_height
+			Return
+		EndIf
+		ratio=Min(gwidth/virt_width,gheight/virt_height)
+		If border_mode&4
+			ratio=Max(Floor(ratio),1)
+		EndIf
+		full_height=gheight/ratio
+		full_width=gwidth/ratio
+		
+		border_x=(full_width-virt_width)*.5
+		border_y=(full_height-virt_height)*.5
+		If border_mode&4
+			border_x=Floor(border_x)
+			border_y=Floor(border_y)
+		EndIf
+		_m2dDriver.SetResolution full_width,full_height
+		
+		adj_vp_x=0;adj_vp_y=0;adj_vp_width=Ceil(full_width)*ratio;adj_vp_height=Ceil(full_height)*ratio
+		_m2dDriver.SetViewport adj_vp_x,adj_vp_y,adj_vp_width,adj_vp_height
+		
+	End Method
+	
+	Method SetBorderMode( Mode:Int )
+		border_mode=Mode
+		SetResolution virt_width,virt_height
+	End Method
+	
+	Method SetBorderColor( red:Int, green:Int, blue:Int )
+		border_red=red
+		border_green=green
+		border_blue=blue
+	End Method
+	
+	Method ClearBorder()
+		If border_mode&1
+			Local rot:Float=GetRotation()
+			Local ox:Float,oy:Float;GetOrigin ox,oy
+			Local hx:Float,hy:Float;GetHandle hx,hy
+			Local sx:Float, sy:Float;GetScale sx,sy
+			_m2dDriver.SetViewport 0,0,Int(Ceil(full_width)*ratio),Int(Ceil(full_height)*ratio)
+			_m2dDriver.SetColor border_red,border_green,border_blue
+			_m2dDriver.SetAlpha 1
+			SetRotation 0
+			SetOrigin 0,0
+			SetHandle 0,0
+			SetScale 1,1
+			_m2dDriver.SetBlend SOLIDBLEND
+			_m2dDriver.DrawRect -1,-1,full_width+1,border_y,0,0
+			_m2dDriver.DrawRect -1,border_y+virt_height,full_width+1,full_height+1,0,0
+			_m2dDriver.DrawRect -1,border_y-1,border_x,border_y+virt_height+1,0,0
+			_m2dDriver.DrawRect border_x+virt_width,border_y-1,full_width+1,border_y+virt_height+1,0,0
+			SetColor m2d_red,m2d_green,m2d_blue
+			_m2dDriver.SetAlpha m2d_alpha
+			SetRotation rot
+			SetOrigin ox,oy
+			SetHandle hx,hy
+			SetScale sx,sy
+			SetBlend m2d_blend
+			_m2dDriver.SetViewport adj_vp_x,adj_vp_y,adj_vp_width,adj_vp_height
+		EndIf
+	End Method
+	
+	Method SetScreenRotation( rot:Float )
+		tform_scr_rot=rot
+		UpdateTransform
+	End Method
+	
+	Method SetZoom( zoom:Float )
+		tform_scr_zoom=zoom
+		UpdateTransform
+	End Method
+	
+	Method SetFocus( x:Float, y:Float )
+		focus_x=x
+		focus_y=y
+	End Method
+	
+	Method SetMidFocus()
+		focus_x=virt_width*.5
+		focus_y=virt_height*.5
+	End Method
+	
+	Method OddMouse( x:Float Var, y:Float Var )
+		Local ox:Float,oy:Float;GetOrigin ox,oy
+		Local s#=Sin(tform_scr_rot), c#=Cos(tform_scr_rot)
+		Local ix#= c/tform_scr_zoom, jx#= s/tform_scr_zoom
+		Local iy#=-s/tform_scr_zoom, jy#= c/tform_scr_zoom
+		Local xscale:Float=full_width/virt_width
+		Local yscale:Float=full_height/virt_height
+		x=VirtualMouseX()*(full_width/virt_width)-border_x-focus_x
+		y=VirtualMouseY()*(full_height/virt_height)-border_y-focus_y
+		Local tmp_x:Float=x
+		x=x*ix+y*iy-ox
+		y=tmp_x*jx+y*jy-oy
+	End Method
+	
+	Method DrawPolyImage( xyuv#[],iframe:TImageFrame,handlex#,handley#,originx#,originy# ) Abstract
+
+	Method UpdateTransform()
+		Local s#=Sin(-tform_scr_rot)
+		Local c#=Cos(-tform_scr_rot)
+		tform_scr_ix= c*tform_scr_zoom
+		tform_scr_iy=-s*tform_scr_zoom
+		tform_scr_jx= s*tform_scr_zoom
+		tform_scr_jy= c*tform_scr_zoom
+	End Method
+	
+	Method TransformPoint( x:Float Var, y:Float Var )
+		Local tmp_x:Float=x
+		x=x*tform_scr_ix+y*tform_scr_iy
+		y=tmp_x*tform_scr_jx+y*tform_scr_jy
+	End Method
+	
+	Method InitFields()
+		border_red=0
+		border_green=0
+		border_blue=0
+		border_mode=BORDER_NONE
+		border_x=0
+		border_y=0
+		full_width=GraphicsWidth()
+		full_height=GraphicsHeight()
+		virt_width=full_width
+		virt_height=full_height
+		tform_scr_rot=0
+		tform_scr_zoom=1
+		UpdateTransform
+	
+		focus_x=0
+		focus_y=0
+		
+		m2d_blend=MASKBLEND
+		m2d_alpha=1
+		m2d_linewidth=1
+		m2d_clsred=0;m2d_clsgreen=0;m2d_clsblue=0
+		m2d_red=255;m2d_green=255;m2d_blue=255
+	End Method
+
+End Type
+
+Rem
+bbdoc: Sets how borders displayed
+about: Sets how borders will be displayed if the virtual aspect ratio is not the same as the screens aspect ratio.
+
+The available modes are:
+[ @BORDER_NONE | Stretches/distorts the display to fit the screen. This is the default Max2D behaviour
+* @BORDER_LETTERBOX_FILL | Scales the display to fit the screen but maintains it's aspect ratio. Any draw space left around it is @not clipped
+* @BORDER_LETTERBOX_SOLID | Scales the display to fit the screen but maintains it's aspect ratio. Any draw space left around it is clipped
+* @BORDER_BESTFIT_FILL | Scales the display by whole numbers only whilst maintaining it's aspect ratio. Any draw space left around it is @not clipped
+* @BORDER_BESTFIT_SOLID | Scales the display by whole numbers only whilst maintaining it's aspect ratio. Any draw space left around it is clipped
+]
+End Rem
+Function SetBorderMode( Mode:Int )
+	_odd2dDriver.SetBorderMode Mode
+End Function
+
+Rem
+bbdoc: Set current border color
+about:
+The @red, @green and @blue parameters should be in the range of 0 to 255.
+
+The default border color is black.
+End Rem
+Function SetBorderColor( red:Int, green:Int, blue:Int )
+	_odd2dDriver.SetBorderColor red,green,blue
+End Function
+
+Rem
+bbdoc: Set screen rotation
+about:
+@rotation is given in degrees and should be in the range 0 to 360.
+
+#SetScreenRotation rotates the whole display around the focus.
+End Rem
+Function SetScreenRotation( rot:Float )
+	_odd2dDriver.SetScreenRotation rot
+End Function
+
+Rem
+bbdoc: Set current screen zoom
+about:
+Zooms the display in or out centered upon the focus.
+End Rem
+Function SetZoom( zoom:Float )
+	_odd2dDriver.SetZoom zoom
+End Function
+
+Rem
+bbdoc: Set display focus
+about:
+The screen focus is a 2D offset added to the x,y location of all 
+drawing commands. It is applied after all other transforms and can be thought of as the screens handle.
+
+In Max2D the focus is allways the top lext of the screen meaning all other cammands ultimately take their origin from that,
+#SetScreenFocus allows you to change this behaviour.
+End Rem
+Function SetScreenFocus( x:Float, y:Float )
+	_odd2dDriver.SetFocus x,y
+End Function
+
+Rem
+bbdoc: Sets the screen focus to the center of the display
+End Rem
+Function SetMidFocus()
+	_odd2dDriver.SetMidFocus
+End Function
+
+Rem
+bbdoc: Gets the current position of the mouse
+about: Sets @x and @y to the current mouse position using the draw coordinates.
+EndRem
+Function OddMouse( x:Float Var, y:Float Var )
+	_odd2dDriver.OddMouse x,y
+End Function
+
+Rem
+bbdoc: Draw a polygon using image as a texture
+about:
+#DrawPolyImage draws a polygon with corners defined by an array of x#,y# and u#,v# coordinate pairs.
+The u/v coordinates are measured in image pixels.
+
+BlitzMax commands that affect the drawing of polygons include #SetColor, #SetHandle, 
+#SetScale, #SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha.
+End Rem
+Function DrawPolyImage( xyuv:Float[], image:TImage, frame:Int=0 )
+	Local iframe:TImageFrame=image.Frame(frame)
+	If Not iframe Then Return
+	
+	Local handle_x:Float, handle_y:Float, origin_x:Float, origin_y:Float
+	GetHandle handle_x,handle_y;GetOrigin origin_x,origin_y
+	Local rot:Float=GetRotation()
+	Local sclx:Float,scly:Float
+	GetScale sclx,scly
+	SetRotation rot-_odd2dDriver.tform_scr_rot
+	SetScale sclx*_odd2dDriver.tform_scr_zoom,scly*_odd2dDriver.tform_scr_zoom
+	_odd2dDriver.TransformPoint origin_x,origin_y
+	origin_x:+_odd2dDriver.focus_x+_odd2dDriver.border_x
+	origin_y:+_odd2dDriver.focus_y+_odd2dDriver.border_y
+		
+	_odd2ddriver.DrawPolyImage xyuv,iframe,handle_x,handle_y,origin_x,origin_y
+		
+	SetRotation rot
+	SetScale sclx,scly
+End Function
+
+Rem
+bbdoc: Draw an image polygon to the back buffer
+about:
+#DrawImagePoly works the same as #DrawImage except instead of drawing the full image it draws a polygonal portion of it defined by the u,v coordinates. 
+The u/v coordinates are measured in image pixels.
+
+Drawing is affected by the current blend mode, color, scale and rotation.
+
+If the blend mode is ALPHABLEND the image is affected by the current alpha value
+and images with alpha channels are blended correctly with the background.
+End Rem
+Function DrawImagePoly( image:TImage, x:Float, y:Float, uv:Float[], frame:Int=0 )
+	Local iframe:TImageFrame=image.Frame(frame)
+	If Not iframe Then Return
+	
+	Local handle_x:Float, handle_y:Float, origin_x:Float, origin_y:Float
+	GetOrigin origin_x,origin_y
+	origin_x:+x;origin_y:+y
+	Local rot:Float=GetRotation()
+	Local sclx:Float,scly:Float
+	GetScale sclx,scly
+	SetRotation rot-_odd2dDriver.tform_scr_rot
+	SetScale sclx*_odd2dDriver.tform_scr_zoom,scly*_odd2dDriver.tform_scr_zoom
+	_odd2dDriver.TransformPoint origin_x,origin_y
+	origin_x:+_odd2dDriver.focus_x+_odd2dDriver.border_x
+	origin_y:+_odd2dDriver.focus_y+_odd2dDriver.border_y
+	
+	Local segs:Int=uv.length/2
+	Local xyuv:Float[segs*4]
+	For Local i:Int=0 Until segs
+		xyuv[i*4]=uv[i*2]
+		xyuv[i*4+1]=uv[i*2+1]
+		xyuv[i*4+2]=uv[i*2]
+		xyuv[i*4+3]=uv[i*2+1]
+	Next
+		
+	_odd2ddriver.DrawPolyImage xyuv,iframe,image.handle_x,image.handle_y,origin_x,origin_y
+		
+	SetRotation rot
+	SetScale sclx,scly
+End Function