[bmx] Aspect correction for SetVirtualResolution() by Oddball [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:39

Previous topic - Next topic

BlitzBot

Title : Aspect correction for SetVirtualResolution()
Author : Oddball
Posted : 1+ years ago

Description : The new and changed functions are SetVirtualResolution, SetBorderColor and SwitchAspectMode. The other functions only mimic their original, but allow for the aspect changes.

The modes are:
ASPECT_KEEP - Keeps previously selected mode.
ASPECT_STRETCH - This is the classic style.
ASPECT_LETTERBOX_FILL - This mode scales the resolution to fit the screen. Any extra area is not clipped.
ASPECT_LETTERBOX_BORDER - This mode scales the resolution to fit the screen. Any extra area is cleared using the border color.
ASPECT_BESTFIT_FILL - This scales the resolution by integer values only. Any extra space is not clipped.
ASPECT_BESTFIT_BORDER - This scales the resolution by integer values only. Any extra space is cleared using the border color.

There is now a module version for those who prefer that sort of thing:
<a href="http://www.gooeyblob.com/temp/aspectmodule.zip" target="_blank">http://www.gooeyblob.com/temp/aspectmodule.zip</a>

Enjoy!


Code :
Code: blitzmax
'Code: David 'Oddball' Williamson
'6th May 2010
'Enjoy!

SuperStrict

Const ASPECT_KEEP:Int=1
Const ASPECT_STRETCH:Int=0
Const ASPECT_LETTERBOX_FILL:Int=2
Const ASPECT_LETTERBOX_BORDER:Int=3
Const ASPECT_BESTFIT_FILL:Int=4
Const ASPECT_BESTFIT_BORDER:Int=5	'Bestfit border may not work with all drivers(i.e. DirectX)

Private

Global _xoffset:Float
Global _yoffset:Float
Global _vwidth:Float
Global _vheight:Float
Global _mode:Int=ASPECT_STRETCH
Global _bred:Int=0
Global _bgreen:Int=0
Global _bblue:Int=0

Public

Function SetVirtualResolution( width:Float, height:Float, mode:Int=ASPECT_KEEP )
	If mode<>ASPECT_KEEP Then _mode=mode
	If _mode=ASPECT_STRETCH
		_xoffset=0;_yoffset=0;_vwidth=width;_vheight=height;_mode=mode
		brl.max2d.SetVirtualResolution(_vwidth,_vheight)
		brl.max2d.SetViewport _xoffset,_yoffset,Ceil(_vwidth),Ceil(_vheight)
		brl.max2d.SetOrigin _xoffset,_yoffset
		Return
	EndIf
	Local gwidth:Int=GraphicsWidth()
	Local gheight:Int=GraphicsHeight()
	_vwidth=width
	_vheight=height
	Local wratio:Float=gwidth/_vwidth
	Local hratio:Float=gheight/_vheight
	If wratio<hratio Then hratio=wratio
	If _mode&4
		hratio=Floor(hratio)
		hratio=Max(hratio,1)
	EndIf
	height=gheight/hratio
	width=gwidth/hratio
	
	_xoffset=(width-_vwidth)*.5
	_yoffset=(height-_vheight)*.5
	If _mode&4
		_xoffset=Floor(_xoffset)
		_yoffset=Floor(_yoffset)
	EndIf
	brl.max2d.SetVirtualResolution(width,height)
	
	If _mode&1
		Local red:Int,green:Int,blue:Int
		GetClsColor red,green,blue
		SetClsColor _bred,_bgreen,_bblue
		Cls
		SetClsColor red,green,blue
		brl.max2d.SetViewport _xoffset,_yoffset,_vwidth,_vheight
	Else
		brl.max2d.SetViewport 0,0,Ceil(brl.max2d.VirtualResolutionWidth()),Ceil(brl.max2d.VirtualResolutionHeight())
	EndIf
	
	brl.max2d.SetOrigin _xoffset,_yoffset
	
End Function

Function SetBorderColor( red:Int, green:Int, blue:Int )
	_bred=red
	_bgreen=green
	_bblue=blue
End Function

Function SwitchAspectMode( mode:Int )
	SetVirtualResolution _vwidth,_vheight,mode
End Function

Function Flip( sync:Int=-1 )
	brl.Graphics.Flip sync
	If _mode&1
		brl.max2d.SetViewport 0,0,Ceil(brl.max2d.VirtualResolutionWidth())+1,Ceil(brl.max2d.VirtualResolutionHeight())+1
		Local red:Int,green:Int,blue:Int
		GetClsColor red,green,blue
		SetClsColor _bred,_bgreen,_bblue
		Cls
		SetClsColor red,green,blue
		brl.max2d.SetViewport _xoffset,_yoffset,_vwidth,_vheight
	EndIf
End Function

Function SetOrigin( x:Float, y:Float )
	brl.max2d.SetOrigin x+_xoffset,y+_yoffset
End Function

Function GetOrigin( x:Float Var, y:Float Var )
	brl.max2d.GetOrigin x,y
	x:-_xoffset
	y:-_yoffset
End Function

Function SetViewport( x:Int, y:Int, width:Int, height:Int )
	Local x2:Float=Min(x+width,_xoffset+_vwidth)
	Local y2:Float=Min(y+height,_yoffset+_vheight)
	x=Max(x,_xoffset)
	y=Max(y,_yoffset)
	brl.max2d.SetViewport x,y,x2-x,y2-y
End Function

Function GetViewport( x:Int Var,y:Int Var,width:Int Var,height:Int Var )
	brl.max2d.GetViewport x,y,width,height
	x:-_xoffset
	y:-_yoffset
End Function

Function VirtualMouseX:Float()
	Return brl.max2d.VirtualMouseX()-_xoffset
End Function

Function VirtualMouseY:Float()
	Return brl.max2d.VirtualMouseY()-_yoffset
End Function

Function MoveVirtualtMouse( x:Float, y:Float )
	brl.max2d.MoveVirtualMouse x+_xoffset,y+_yoffset
End Function

Function VirtualResolutionWidth:Float()
	Return _vwidth
End Function

Function VirtualResolutionHeight:Float()
	Return _vheight
End Function

'-----------------------
'Test code
'-----------------------
SeedRnd MilliSecs()
Graphics Rand(320,DesktopWidth()),Rand(240,DesktopHeight())

SetBorderColor 32,32,32
SetClsColor 223,223,223

SetVirtualResolution 320,240,ASPECT_LETTERBOX_BORDER

Repeat
	If KeyHit(KEY_1) Then SwitchAspectMode ASPECT_STRETCH
	If KeyHit(KEY_2) Then SwitchAspectMode ASPECT_LETTERBOX_FILL
	If KeyHit(KEY_3) Then SwitchAspectMode ASPECT_LETTERBOX_BORDER
	If KeyHit(KEY_4) Then SwitchAspectMode ASPECT_BESTFIT_FILL
	If KeyHit(KEY_5) Then SwitchAspectMode ASPECT_BESTFIT_BORDER
	If KeyHit(KEY_SPACE)
		Graphics Rand(320,DesktopWidth()),Rand(240,DesktopHeight())
		SetVirtualResolution 320,240
		SetClsColor 223,223,223
		SetColor 255,127,0
	EndIf
	Cls
	SetColor 0,0,255
	DrawText Int(VirtualMouseX())+","+Int(VirtualMouseY()),VirtualMouseX(),VirtualMouseY()
	SetColor 255,0,0
	DrawText "Aspect correction demo",5,5
	SetColor 255,127,0
	DrawText "[1] Stretch",5,35
	DrawText "[2] Letterbox(no border)",5,50
	DrawText "[3] Letterbox",5,65
	DrawText "[4] Best fit(no border)",5,80
	DrawText "[5] Best fit - May not work with DirectX Drivers",5,95
	DrawText "[SPACE] Resize window(random size)",5,125
	Flip
Until KeyHit(KEY_ESCAPE)


Comments :


Oddball(Posted 1+ years ago)

 Made a couple of corrections. I could make this into a module if there's enough interest.


Oddball(Posted 1+ years ago)

 Added a keep mode and improved the demo code.


Oddball(Posted 1+ years ago)

 Added MoveVirtualMouse.


BlitzSupport(Posted 1+ years ago)

 Very nice. Still hopeful Mark will add aspect ratio correction at some point, but this will do very nicely indeed in the meantime! Thanks.


Oddball(Posted 1+ years ago)

 The module version is a little more complete, but a little less plug-and-play as the function names in the mod are changed to prevent clashes with Max2D.For those with sigs turned off you can get it at:<a href="http://www.gooeyblob.com/temp/aspectmodule.zip" target="_blank">http://www.gooeyblob.com/temp/aspectmodule.zip</a>


LamptonWorm

Just wanted to say thanks for this function, really useful and helped my project, cheers!

Dabz

Off Topic... Mr Lampton Worm... Your not from County Durham by any chance are you?

Dabz
Dell Inspiron 16 Plus 7630 Laptop - 16.0-inch 16:10 2.5K Display, Intel Core i7-13620H Processor, 16 DDR5 RAM, 1, NVIDIA GeForce RTX 4060 GDDR6 Graphics, Windows 11 Piss Flap.