[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) Select
'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
Intel Core i5 6400 2.7GHz, NVIDIA GeForce GTX 1070 (8GB), 16Gig DDR4 RAM, 256GB SSD, 1TB HDD, Windows 10 64bit