.: Configure Screen Resolution on Game Load
|
|
| |
Configuring the screen resolution and colour depth is something that most gamers will want from their games. I have implemented this using an options window that shows the user the supported resolution of his graphics card and then allowing them the chance to choose which resolution to use. Once selected these settings are then applied to the PC. When the game exits the PC is returned to the original settings.
Open your own project or use the tutorial 2 source code and add the following components:
Right-click on the project name in the solution explorer and select add class, call this class ScreenRes and add the following code:
|
|
Public Class ScreenRes
Public Class Resolution
Const CCDEVICENAME As Short = 32
Const CCFORMNAME As Short = 32
Const DM_BITSPERPEL As Integer = &H40000
Const DM_PELSWIDTH As Integer = &H80000
Const DM_PELSHEIGHT As Integer = &H100000
Const CDS_UPDATEREGISTRY As Short = &H1S
Const CDS_TEST As Short = &H4S
Const DISP_CHANGE_SUCCESSFUL As Short = 0
Const DISP_CHANGE_RESTART As Short = 1
Const BITSPIXEL As Short = 12
Private Structure DEVMODE
<VBFixedString(CCDEVICENAME), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=CCDEVICENAME)> Public dmDeviceName As String
Dim dmSpecVersion As Short
Dim dmDriverVersion As Short
Dim dmSize As Short
Dim dmDriverExtra As Short
Dim dmFields As Integer
Dim dmOrientation As Short
Dim dmPaperSize As Short
Dim dmPaperLength As Short
Dim dmPaperWidth As Short
Dim dmScale As Short
Dim dmCopies As Short
Dim dmDefaultSource As Short
Dim dmPrintQuality As Short
Dim dmColor As Short
Dim dmDuplex As Short
Dim dmYResolution As Short
Dim dmTTOption As Short
Dim dmCollate As Short
<VBFixedString(CCFORMNAME), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=CCFORMNAME)> Public dmFormName As String
Dim dmUnusedPadding As Short
Dim dmBitsPerPel As Short
Dim dmPelsWidth As Integer
Dim dmPelsHeight As Integer
Dim dmDisplayFlags As Integer
Dim dmDisplayFrequency As Integer
End Structure
Private Declare Function EnumDisplaySettings Lib "user32" Alias "EnumDisplaySettingsA" (ByVal lpszDeviceName As Integer, ByVal iModeNum As Integer, ByRef lpDevMode As DEVMODE) As Boolean
Private Declare Function ChangeDisplaySettings Lib "user32" Alias "ChangeDisplaySettingsA" (ByRef lpDevMode As DEVMODE, ByVal dwFlags As Integer) As Integer
Public Shared Sub ChangeRes(ByRef X As Integer, ByRef Y As Integer, ByRef Bits As Integer)
Dim DevM As DEVMODE = Nothing
Dim erg As Integer
'Get the info into DevM
erg = EnumDisplaySettings(0, 0, DevM)
'This is what we're going to change
DevM.dmFields = DM_PELSWIDTH Or DM_PELSHEIGHT Or DM_BITSPERPEL
DevM.dmPelsWidth = X 'ScreenWidth
DevM.dmPelsHeight = Y 'ScreenHeight
DevM.dmBitsPerPel = Bits '(can be 8, 16, 24, 32 or even 4)
'Now change the display and check if possible
erg = ChangeDisplaySettings(DevM, CDS_TEST)
End Sub
End Class
End Class
This uses Win32 API's to enumerate and change the screen resolution settings, it also creates a Sub called ChangeRes that can be called from another part of the program, this Sub will implement the change.
Next create a new module and call it GraphicsModule, then add the following code:
Module GraphicsModule
Public XNAGraphicsAdapaterBytePub As Byte = 0
Public ScreenResWidthPub As UShort = 1024
Public ScreenResHeightPub As UShort = 768
Public ScreenResDepthPub As UShort = 32
Public OldResWidthPub As UShort = 1024
Public OldResHeightPub As UShort = 768
Public OldResDepthPub As UShort = 32
End Module
This module holds public variables that will hold both the old and new resolution settings.
Next, we will create a new form and call it GameStart, this form should look as follows:

You can change the layout of the form but it will need a combobox called combo3DAdpater, a combobox called comboRes, a button called btnPlay and another button called btnExit, any changes to these names will require changes to the form code. Both comboboxes should be dropdownlist only so that users cannot type in them. Also, in the project properties change the startup form to GameStart. Once created change to code view and add the following code:
Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Graphics
Imports Microsoft.Xna.Framework.Components
Public Class GameStart
'Create Direct3D Device objects
Dim D3device As Graphics.GraphicsDevice = Nothing
Dim D3presentParams As New PresentationParameters
Dim D3firstadapter As Graphics.GraphicsAdapter = Graphics.GraphicsAdapter.Adapters(0)
Dim D3alladapters As System.Collections.ObjectModel.ReadOnlyCollection(Of Graphics.GraphicsAdapter) = Graphics.GraphicsAdapter.Adapters
Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExit.Click
' The Exit button exits the app
Application.Exit()
End Sub
Private Sub GameStart_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Get Available 3D Adpaters
Dim m As Integer = 0
For m = 0 To D3alladapters.Count - 1
' Insert 3D Adapters to combobox combo3DAdapters
combo3DAdpater.Items.Add(D3alladapters.Item(m).Description.ToString)
Next
'Set combo3DAdapter text to the first entry in combo3DAdapter list
combo3DAdpater.Text = combo3DAdpater.Items.Item(0)
' Create 3D Device Display mode info
Dim SupportedModes As DisplayModeCollection = D3firstadapter.SupportedDisplayModes
Dim ADisplayMode As DisplayMode
Dim n As Integer = 0
Dim str As String = ""
For Each ADisplayMode In SupportedModes
'If the Supported Display mode has width bigger than 640 and height bigger than 400
' and has a colour depth of either X8R8G8B8=32bit or R5G6B5=16 bit then take ot of them
If ADisplayMode.Width >= 640 AndAlso ADisplayMode.Height >= 480 AndAlso _
(ADisplayMode.Format = SurfaceFormat.Bgr32 Or ADisplayMode.Format = SurfaceFormat.Bgr565) Then
' Change Colour depth from computer format to normal format
If ADisplayMode.Format.ToString = "Bgr32" Then
str = "32"
ElseIf ADisplayMode.Format.ToString = "Bgr565" Then
str = "16"
End If
'Add DisplayModes to combobox comboRes
If comboRes.Items.Contains(ADisplayMode.Width & " x " & _
ADisplayMode.Height & " - " & str & "bit") = False Then
If ADisplayMode.Width > ADisplayMode.Height Then
comboRes.Items.Add(ADisplayMode.Width & " x " & ADisplayMode.Height & " - " & str & "bit")
End If
End If
End If
Next
'Set comboRes text to the current screen resolution
comboRes.Text = My.Computer.Screen.Bounds.Width.ToString & " x " & _
My.Computer.Screen.Bounds.Height.ToString & " - " & My.Computer.Screen.BitsPerPixel & "bit"
'Clear Variables
SupportedModes = Nothing
ADisplayMode = Nothing
n = Nothing
str = Nothing
m = Nothing
End Sub
Private Sub btnPlay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPlay.Click
'Set chosen Graphics adapter index to XNAGraphicsAdapaterInteger
Dim m As Integer = 0
For m = 0 To D3alladapters.Count - 1
If combo3DAdpater.Text = D3alladapters.Item(m).Description.ToString Then
XNAGraphicsAdapaterBytePub = m
End If
Next
'gather Current Screen resolution and set to public variables
OldResWidthPub = My.Computer.Screen.Bounds.Size.Width
OldResHeightPub = My.Computer.Screen.Bounds.Height
OldResDepthPub = My.Computer.Screen.BitsPerPixel
'Set chosen Screen resolution to public variables
ScreenResWidthPub = (Mid(comboRes.Text, 1, InStr(comboRes.Text, " x ", CompareMethod.Text))).ToString
ScreenResHeightPub = Mid(comboRes.Text, (InStr(comboRes.Text, " x ", CompareMethod.Text) + 3), _
(InStr(comboRes.Text, " - ", CompareMethod.Text) - (InStr(comboRes.Text, " x ", CompareMethod.Text) + 3)))
ScreenResDepthPub = Microsoft.VisualBasic.Left(Microsoft.VisualBasic.Right(comboRes.Text, 5), 2)
My.Forms.Form1.Show()
Me.Hide()
End Sub
End Class
I have tried to explain what the code does as i have written it, but to summarize, The list of available graphics adapters is determined and added to combo3DAdapters. The supported displaymodes for the current adapter is them add to comboRes, only resolution above 640x480 and colour depths of either 16 or 32 bit are added. The Exit button exits the application. The Play button determines which adapter has been selected and stores the number in the public variable XNAGraphicsAdapterBytepub, this variable is a byte because i assume that no PC has more than 255 graphics adapters. The original screen resolutions are stored in their respective variables as are the new resolutions. The last action is to load form1 and hide this form.
Next we must configure form1 to use the whole screen, in the form1 code add the following:
In the InitializeGraphics() function add the following code:
ScreenRes.Resolution.ChangeRes(ScreenResWidthPub, ScreenResHeightPub, ScreenResDepthPub)
This changes the screen resolution using the screen resolution selected by the user.
In the Form1_Load event add the following code:
Me.Bounds = My.Computer.Screen.Bounds
This ensures that the form uses the whole window, next configure the form designer so that :
FormBorderStyle = None
and lastly add the following code to the Form1_Closing function:
Try
ScreenRes.Resolution.ChangeRes(OldResWidthPub, OldResHeightPub, OldResDepthPub)
Catch ex As Exception
MsgBox(ex.Message)
Application.Exit()
End Try
This code returns the screen resolution to its original settings when the app closes. Thats it, now run the program and you will be able to select what screen resolution your game runs at.
Please now return to the tutorials page for the next tutorial.
ScreenResolution Source Code - 54Kb
Web site contents © Copyright Alan Phipps 2006, All rights reserved.
Website templates |