Updated version of OTHGMars' updated window and resolution options modes.

Additional changes include disabling certain options when they are not valid(ie, resolution is disabled when in borderless mode)
This commit is contained in:
Areloch 2020-09-20 02:06:15 -05:00
parent d76c73c252
commit 26ef40950b
12 changed files with 559 additions and 152 deletions

View file

@ -54,102 +54,77 @@ $WORD::FULLSCREEN = 2;
$WORD::BITDEPTH = 3;
$WORD::REFRESH = 4;
$WORD::AA = 5;
$Video::ModeTags = "Windowed\tBorderless\tFullscreen";
$Video::ModeWindowed = 0;
$Video::ModeBorderless = 1;
$Video::ModeFullscreen = 2;
$Video::minimumXResolution = 1024;
$Video::minimumYResolution = 720;
function configureCanvas()
{
// Setup a good default if we don't have one already.
if ($pref::Video::Resolution $= "")
$pref::Video::Resolution = "800 600";
if ($pref::Video::FullScreen $= "")
$pref::Video::FullScreen = false;
if ($pref::Video::BitDepth $= "")
$pref::Video::BitDepth = "32";
if ($pref::Video::RefreshRate $= "")
$pref::Video::RefreshRate = "60";
if ($pref::Video::AA $= "")
$pref::Video::AA = "4";
if (($pref::Video::deviceId $= "") || ($pref::Video::deviceId < 0) ||
($pref::Video::deviceId >= Canvas.getMonitorCount()))
$pref::Video::deviceId = 0; // Monitor 0
if (($pref::Video::deviceMode $= "") || ($pref::Video::deviceMode < 0) ||
($pref::Video::deviceMode >= getFieldCount($Video::ModeTags)))
{
$pref::Video::deviceMode = $Video::ModeBorderless;
$pref::Video::mode = Canvas.getBestCanvasRes($pref::Video::deviceId, $pref::Video::deviceMode);
Canvas.modeStrToPrefs($pref::Video::mode);
}
if($cliFullscreen !$= "")
$pref::Video::deviceMode = $cliFullscreen ? 2 : 0;
// Default to borderless at desktop resolution if there is no saved pref or
// command line arg
if (($pref::Video::Resolution $= "") || ($pref::Video::Resolution.x < $Video::minimumXResolution) ||
($pref::Video::Resolution.y < $Video::minimumYResolution))
{
$pref::Video::mode = Canvas.getBestCanvasRes($pref::Video::deviceId, $pref::Video::deviceMode);
Canvas.modeStrToPrefs($pref::Video::mode);
}
if ($pref::Video::deviceMode != $Video::ModeFullscreen)
$pref::Video::FullScreen = false;
%modeStr = Canvas.prefsToModeStr();
echo("--------------");
echo("Attempting to set resolution to \"" @ %modeStr @ "\"");
// Make sure we are running at a valid resolution
if (!Canvas.checkCanvasRes(%modeStr, $pref::Video::deviceId, $pref::Video::deviceMode, true))
{
%modeStr = Canvas.getBestCanvasRes($pref::Video::deviceId, $pref::Video::deviceMode);
Canvas.modeStrToPrefs(%modeStr);
}
%fsLabel = getField($Video::ModeTags, $pref::Video::deviceMode);
%resX = $pref::Video::Resolution.x;
%resY = $pref::Video::Resolution.y;
%fs = $pref::Video::FullScreen;
%bpp = $pref::Video::BitDepth;
%bpp = $pref::Video::BitDepth;
%rate = $pref::Video::RefreshRate;
%aa = $pref::Video::AA;
if($cliFullscreen !$= "") {
%fs = $cliFullscreen;
$cliFullscreen = "";
}
echo("--------------");
echo("Attempting to set resolution to \"" @ %resX SPC %resY SPC %fs SPC %bpp SPC %rate SPC %aa @ "\"");
%deskRes = getDesktopResolution();
%deskResX = getWord(%deskRes, $WORD::RES_X);
%deskResY = getWord(%deskRes, $WORD::RES_Y);
%deskResBPP = getWord(%deskRes, 2);
// We shouldn't be getting this any more but just in case...
if (%bpp $= "Default")
%bpp = %deskResBPP;
// Make sure we are running at a valid resolution
if (%fs $= "0" || %fs $= "false")
{
// Windowed mode has to use the same bit depth as the desktop
%bpp = %deskResBPP;
// Windowed mode also has to run at a smaller resolution than the desktop
if ((%resX >= %deskResX) || (%resY >= %deskResY))
{
warn("Warning: The requested windowed resolution is equal to or larger than the current desktop resolution. Attempting to find a better resolution");
%resCount = Canvas.getModeCount();
for (%i = (%resCount - 1); %i >= 0; %i--)
{
%testRes = Canvas.getMode(%i);
%testResX = getWord(%testRes, $WORD::RES_X);
%testResY = getWord(%testRes, $WORD::RES_Y);
%testBPP = getWord(%testRes, $WORD::BITDEPTH);
if (%testBPP != %bpp)
continue;
if ((%testResX < %deskResX) && (%testResY < %deskResY))
{
// This will work as our new resolution
%resX = %testResX;
%resY = %testResY;
warn("Warning: Switching to \"" @ %resX SPC %resY SPC %bpp @ "\"");
break;
}
}
}
}
$pref::Video::Resolution = %resX SPC %resY;
$pref::Video::FullScreen = %fs;
$pref::Video::BitDepth = %bpp;
$pref::Video::RefreshRate = %rate;
$pref::Video::AA = %aa;
if (%fs == 1 || %fs $= "true")
%fsLabel = "Yes";
else
%fsLabel = "No";
%fsaa = $pref::Video::AA;
%fs = ($pref::Video::deviceMode == 2);
echo("Accepted Mode: " NL
"--Resolution : " @ %resX SPC %resY NL
"--Full Screen : " @ %fsLabel NL
"--Resolution : " @ %resX SPC %resY NL
"--Screen Mode : " @ %fsLabel NL
"--Bits Per Pixel : " @ %bpp NL
"--Refresh Rate : " @ %rate NL
"--AA TypeXLevel : " @ %aa NL
"--Refresh Rate : " @ %rate NL
"--FSAA Level : " @ %fsaa NL
"--------------");
// Actually set the new video mode
Canvas.setVideoMode(%resX, %resY, %fs, %bpp, %rate, %aa);
Canvas.setFocus();
// Lock and unlock the mouse to force the position to sync with the platform window
lockMouse(true);
lockMouse(false);
commandToServer('setClientAspectRatio', %resX, %resY);
@ -157,6 +132,97 @@ function configureCanvas()
// We need to parse the setting between AA modes, and then it's level
// It's formatted as AATypexAALevel
// So, FXAAx4 or MLAAx2
if ( isObject( FXAAPostFX ) )
FXAAPostFX.isEnabled = ( %aa > 0 ) ? true : false;
if ( isObject( FXAA_PostEffect ) )
FXAA_PostEffect.isEnabled = ( %aa > 0 ) ? true : false;
}
function GuiCanvas::modeStrToPrefs(%this, %modeStr)
{
$pref::Video::Resolution = %modeStr.x SPC %modeStr.y;
$pref::Video::FullScreen = getWord(%modeStr, $WORD::FULLSCREEN);
$pref::Video::BitDepth = getWord(%modeStr, $WORD::BITDEPTH);
$pref::Video::RefreshRate = getWord(%modeStr, $WORD::REFRESH);
$pref::Video::AA = getWord(%modeStr, $WORD::AA);
}
function GuiCanvas::prefsToModeStr(%this)
{
%modeStr = $pref::Video::Resolution SPC $pref::Video::FullScreen SPC
$pref::Video::BitDepth SPC $pref::Video::RefreshRate SPC $pref::Video::AA;
return %modeStr;
}
function GuiCanvas::checkCanvasRes(%this, %mode, %deviceId, %deviceMode, %startup)
{
%resX = getWord(%mode, $WORD::RES_X);
%resY = getWord(%mode, $WORD::RES_Y);
// Make sure it meets the minimum resolution requirement
if ((%resX < $Video::minimumXResolution) || (%resY < $Video::minimumYResolution))
return false;
if (%deviceMode == $Video::ModeWindowed)
{ // Windowed must be smaller than the device usable area
%deviceRect = getWords(%this.getMonitorUsableRect(%deviceId), 2);
if ((%resY > %deviceRect.y) || (%resX > (%deviceRect.x - 2)))
return false;
return true;
}
else if (%deviceMode == $Video::ModeBorderless)
{ // Borderless must be at or less than the device res
%deviceRect = getWords(%this.getMonitorRect(%deviceId), 2);
if ((%resX > %deviceRect.x) || (%resY > %deviceRect.y))
return false;
return true;
}
if (!%startup)
return true;
// Checking saved prefs, make sure the mode still exists
%bpp = getWord(%mode, $WORD::BITDEPTH);
%rate = getWord(%mode, $WORD::REFRESH);
%resCount = %this.getMonitorModeCount(%deviceId);
for (%i = (%resCount - 1); %i >= 0; %i--)
{
%testRes = %this.getMonitorMode(%deviceId, %i);
%testResX = getWord(%testRes, $WORD::RES_X);
%testResY = getWord(%testRes, $WORD::RES_Y);
%testBPP = getWord(%testRes, $WORD::BITDEPTH);
%testRate = getWord(%testRes, $WORD::REFRESH);
if ((%testResX == %resX) && (%testResY == %resY) &&
(%testBPP == %bpp) && (%testRate == %rate))
return true;
}
return false;
}
// Find the best video mode setting for the device and display mode
function GuiCanvas::getBestCanvasRes(%this, %deviceId, %deviceMode)
{
if (%deviceMode == $Video::ModeWindowed)
%deviceRect = getWords(%this.getMonitorUsableRect(%deviceId), 2);
else
%deviceRect = getWords(%this.getMonitorRect(%deviceId), 2);
%resCount = %this.getModeCount();
for (%i = %resCount - 1; %i >= 0; %i--)
{
%testRes = %this.getMode(%i);
%resX = getWord(%testRes, $WORD::RES_X);
%resY = getWord(%testRes, $WORD::RES_Y);
if ((%resX > %deviceRect.x) || (%resY > %deviceRect.y))
continue;
return %testRes;
}
// Nothing found? return first mode
return %this.getMonitorMode(%deviceId, 0);
}

View file

@ -721,14 +721,19 @@ function _makePrettyResString( %resString, %giveAspectRation )
return %outRes;
}
function getScreenResolutionList()
function getScreenResolutionList(%deviceID, %deviceMode)
{
%returnsList = "";
%resCount = Canvas.getModeCount();
for (%i = 0; %i < %resCount; %i++)
{
%testResString = Canvas.getMode( %i );
// Make sure it's valid for the monitor and mode selections
if (!Canvas.checkCanvasRes(%testResString, %deviceID, %deviceMode, false))
continue;
%testRes = _makePrettyResString( %testResString );
//sanitize
@ -747,11 +752,40 @@ function getScreenResolutionList()
if(%found)
continue;
if(%i != 0)
if(%returnsList !$= "")
%returnsList = %returnsList @ "\t" @ %testRes;
else
%returnsList = %testRes;
}
return %returnsList;
}
// Return a sorted tab-separated list of all refresh rates available for %resolution.
function getScreenRefreshList(%resolution)
{
%rateArray = new ArrayObject();
%resCount = Canvas.getModeCount();
for (%i = 0; %i < %resCount; %i++)
{
%testRes = Canvas.getMode(%i);
if ((%testRes.x != %resolution.x) || (%testRes.y != %resolution.y))
continue;
%rate = getWord(%testRes, $WORD::REFRESH);
if (%rateArray.getIndexFromKey(%rate) == -1)
%rateArray.add(%rate, %rate);
}
%rateArray.sort(true);
%returnsList = "";
for (%i = 0; %i < %rateArray.count(); %i++)
{
%rate = %rateArray.getKey(%i);
%returnsList = %returnsList @ ((%i == 0) ? %rate : ("\t" @ %rate));
}
if (%returnsList $= "")
%returnsList = "60";
%rateArray.delete();
return %returnsList;
}

View file

@ -27,11 +27,6 @@ $sceneLighting::cacheLighting = 1;
$pref::Video::displayDevice = "D3D11";
$pref::Video::disableVerticalSync = 1;
$pref::Video::Resolution = "1024 768";
$pref::Video::FullScreen = false;
$pref::Video::BitDepth = "32";
$pref::Video::RefreshRate = "60";
$pref::Video::AA = "4";
$pref::Video::defaultFenceCount = 0;
$pref::Video::screenShotSession = 0;
$pref::Video::screenShotFormat = "PNG";

View file

@ -196,13 +196,44 @@ function OptionsMenu::populateDisplaySettingsList(%this)
OptionName.setText("");
OptionDescription.setText("");
%resolutionList = getScreenResolutionList();
OptionsMenuSettingsList.addOptionRow("Display API", "D3D11\tOpenGL", false, "", -1, -30, true, "The display API used for rendering.", $pref::Video::displayDevice);
OptionsMenuSettingsList.addOptionRow("Resolution", %resolutionList, false, "", -1, -30, true, "Resolution of the game window", _makePrettyResString( $pref::Video::mode ));
OptionsMenuSettingsList.addOptionRow("Fullscreen", "No\tYes", false, "", -1, -30, true, "", convertBoolToYesNo($pref::Video::FullScreen));
OptionsMenuSettingsList.addOptionRow("VSync", "No\tYes", false, "", -1, -30, true, "", convertBoolToYesNo(!$pref::Video::disableVerticalSync));
OptionsMenuSettingsList.addOptionRow("Refresh Rate", "30\t60\t75", false, "", -1, -30, true, "", $pref::Video::RefreshRate);
%numDevices = Canvas.getMonitorCount();
%devicesList = "";
for(%i = 0; %i < %numDevices; %i++)
{
%device = (%i+1) @ " - " @ Canvas.getMonitorName(%i);
if(%i==0)
%devicesList = %device;
else
%devicesList = %devicesList @ "\t" @ %device;
}
%selectedDevice = getField(%devicesList, $pref::Video::deviceId);
OptionsMenuSettingsList.addOptionRow("Display Device", %devicesList, false, "onDisplayModeChange", -1, -30, true, "The display devices the window should be on.", %selectedDevice);
if (%numDevices > 1)
OptionsMenuSettingsList.setRowEnabled(1, true);
else
OptionsMenuSettingsList.setRowEnabled(1, false);
%mode = getField($Video::ModeTags, $pref::Video::deviceMode);
OptionsMenuSettingsList.addOptionRow("Window Mode", $Video::ModeTags, false, "onDisplayModeChange", -1, -30, true, "", %mode);
%resolutionList = getScreenResolutionList($pref::Video::deviceId, $pref::Video::deviceMode);
OptionsMenuSettingsList.addOptionRow("Resolution", %resolutionList, false, "onDisplayResChange", -1, -30, true, "Resolution of the game window", _makePrettyResString( $pref::Video::mode ));
//If they're doing borderless, the window resolution must match the display resolution
if(%mode !$= "Borderless")
OptionsMenuSettingsList.setRowEnabled(3, true);
else
OptionsMenuSettingsList.setRowEnabled(3, false);
OptionsMenuSettingsList.addOptionRow("VSync", "No\tYes", false, "", -1, -30, true, "", convertBoolToYesNo(!$pref::Video::disableVerticalSync));
%refreshList = getScreenRefreshList($pref::Video::mode);
OptionsMenuSettingsList.addOptionRow("Refresh Rate", %refreshList, false, "", -1, -30, true, "", $pref::Video::RefreshRate);
//move to gameplay tab
OptionsMenuSettingsList.addSliderRow("Field of View", 75, 5, "65 100", "", -1, -30);
@ -215,20 +246,8 @@ function OptionsMenu::populateDisplaySettingsList(%this)
function OptionsMenu::applyDisplaySettings(%this)
{
//%newAdapter = GraphicsMenuDriver.getText();
//%numAdapters = GFXInit::getAdapterCount();
%newDevice = OptionsMenuSettingsList.getCurrentOption(0);
/*for( %i = 0; %i < %numAdapters; %i ++ )
{
%targetAdapter = GFXInit::getAdapterName( %i );
if( GFXInit::getAdapterName( %i ) $= %newDevice )
{
%newDevice = GFXInit::getAdapterType( %i );
break;
}
}*/
// Change the device.
if ( %newDevice !$= $pref::Video::displayDevice )
{
@ -324,9 +343,16 @@ function OptionsMenu::applyGraphicsSettings(%this)
$pref::Video::defaultAnisotropy = %level;
}
updateDisplaySettings();
%newFSAA = OptionsMenuSettingsList.getCurrentOption(9);
if (%newFSAA $= "off")
%newFSAA = 0;
if (%newFSAA !$= $pref::Video::AA)
{
$pref::Video::AA = %newFSAA;
configureCanvas();
}
echo("Exporting client prefs");
%prefPath = getPrefpath();
export("$pref::*", %prefPath @ "/clientPrefs.cs", false);
@ -335,37 +361,58 @@ function OptionsMenu::applyGraphicsSettings(%this)
function updateDisplaySettings()
{
//Update the display settings now
$pref::Video::Resolution = getWord(OptionsMenuSettingsList.getCurrentOption(1), 0) SPC getWord(OptionsMenuSettingsList.getCurrentOption(1), 2);
%newBpp = 32; // ... its not 1997 anymore.
$pref::Video::FullScreen = convertOptionToBool(OptionsMenuSettingsList.getCurrentOption(2)) == 0 ? "false" : "true";
$pref::Video::RefreshRate = OptionsMenuSettingsList.getCurrentOption(4);
%newVsync = !convertOptionToBool(OptionsMenuSettingsList.getCurrentOption(3));
//$pref::Video::AA = GraphicsMenuAA.getSelected();
/*if ( %newFullScreen $= "false" )
{
// If we're in windowed mode switch the fullscreen check
// if the resolution is bigger than the desktop.
%deskRes = getDesktopResolution();
%deskResX = getWord(%deskRes, $WORD::RES_X);
%deskResY = getWord(%deskRes, $WORD::RES_Y);
if ( getWord( %newRes, $WORD::RES_X ) > %deskResX ||
getWord( %newRes, $WORD::RES_Y ) > %deskResY )
{
$pref::Video::FullScreen = "true";
GraphicsMenuFullScreen.setStateOn( true );
}
}*/
%deviceName = OptionsMenuSettingsList.getCurrentOption(1);
%newDeviceID = getWord(%deviceName, 0) - 1;
%deviceModeName = OptionsMenuSettingsList.getCurrentOption(2);
%newDeviceMode = 0;
foreach$(%modeName in $Video::ModeTags)
{
if (%deviceModeName $= %modeName)
break;
else
%newDeviceMode++;
}
%newRes = getWord(OptionsMenuSettingsList.getCurrentOption(3), 0) SPC getWord(OptionsMenuSettingsList.getCurrentOption(3), 2);
%newBpp = 32; // ... its not 1997 anymore.
%newFullScreen = %deviceModeName $= "Fullscreen" ? true : false;
%newRefresh = OptionsMenuSettingsList.getCurrentOption(5);
%newVsync = !convertOptionToBool(OptionsMenuSettingsList.getCurrentOption(4));
%newFSAA = $pref::Video::AA;
// Build the final mode string.
%newMode = $pref::Video::Resolution SPC $pref::Video::FullScreen SPC %newBpp SPC $pref::Video::RefreshRate SPC $pref::Video::AA;
%newMode = %newRes SPC %newFullScreen SPC %newBpp SPC %newRefresh SPC %newFSAA;
// Change the video mode.
if ( %newMode !$= $pref::Video::mode ||
%newVsync != $pref::Video::disableVerticalSync )
if ( %newMode !$= $pref::Video::mode || %newDeviceID != $pref::Video::deviceId ||
%newVsync != $pref::Video::disableVerticalSync || %newDeviceMode != $pref::Video::deviceMode)
{
if ( %testNeedApply )
return true;
//****Edge Case Hack
// If we're in fullscreen mode and switching to a different monitor at the
// same resolution and maintaining fullscreen, GFX...WindowTarget::resetMode()
// will early-out because there is no "mode change" and the monitor change
// will not get applied. Instead of modifying platform code, we're going to
// move onto the new monitor in borderless and immediately switch to FS.
if (%newFullScreen && $pref::Video::FullScreen &&
($pref::Video::Resolution $= %newRes) && ($pref::Video::deviceId != %newDeviceID))
{
$pref::Video::deviceId = %newDeviceID;
$pref::Video::deviceMode = $Video::ModeBorderless;
%tmpModeStr = Canvas.getMonitorMode(%newDeviceID, 0);
Canvas.setVideoMode(%tmpModeStr.x, %tmpModeStr.y, false, 32, getWord(%tmpModeStr, $WORD::REFRESH), %aa);
}
$pref::Video::mode = %newMode;
$pref::Video::disableVerticalSync = %newVsync;
$pref::Video::disableVerticalSync = %newVsync;
$pref::Video::deviceId = %newDeviceID;
$pref::Video::deviceMode = %newDeviceMode;
$pref::Video::Resolution = %newRes;
$pref::Video::FullScreen = %newFullScreen;
$pref::Video::RefreshRate = %newRefresh;
$pref::Video::AA = %newFSAA;
configureCanvas();
}
}
@ -537,4 +584,76 @@ function convertBoolToOnOff(%val)
return "On";
else
return "Off";
}
function onDisplayModeChange(%val)
{
// The display device (monitor) or screen mode has changed. Refill the
// resolution list with only available options.
%deviceName = OptionsMenuSettingsList.getCurrentOption(1);
%newDeviceID = getWord(%deviceName, 0) - 1;
%deviceModeName = OptionsMenuSettingsList.getCurrentOption(2);
%newDeviceMode = 0;
foreach$(%modeName in $Video::ModeTags)
{
if (%deviceModeName $= %modeName)
break;
else
%newDeviceMode++;
}
%resolutionList = getScreenResolutionList(%newDeviceID, %newDeviceMode);
// If we're switching to borderless, default to monitor res
if (%newDeviceMode == $Video::ModeBorderless)
%newRes = getWords(Canvas.getMonitorRect(%newDeviceID), 2);
else
{ // Otherwise, if our old resolution is still in the list, attempt to reset it.
%oldRes = getWord(OptionsMenuSettingsList.getCurrentOption(3), 0) SPC getWord(OptionsMenuSettingsList.getCurrentOption(3), 2);
%found = false;
%retCount = getFieldCount(%resolutionList);
for (%i = 0; %i < %retCount; %i++)
{
%existingEntry = getField(%resolutionList, %i);
if ((%existingEntry.x $= %oldRes.x) && (%existingEntry.z $= %oldRes.y))
{
%found = true;
%newRes = %oldRes;
break;
}
}
if (!%found)
{ // Pick the best resoltion available for the device and mode
%newRes = Canvas.getBestCanvasRes(%newDeviceID, %newDeviceMode);
}
}
if(%newDeviceMode == $Video::ModeBorderless)
OptionsMenuSettingsList.setRowEnabled(3, false);
else
OptionsMenuSettingsList.setRowEnabled(3, true);
OptionsMenuSettingsList.setOptions(3, %resolutionList);
OptionsMenuSettingsList.selectOption(3, _makePrettyResString(%newRes));
}
function onDisplayResChange(%val)
{ // The resolution has changed. Setup refresh rates available at this res.
%newRes = getWord(OptionsMenuSettingsList.getCurrentOption(3), 0) SPC getWord(OptionsMenuSettingsList.getCurrentOption(3), 2);
%refreshList = getScreenRefreshList(%newRes);
// If our old rate still exists, select it
%oldRate = OptionsMenuSettingsList.getCurrentOption(5);
%retCount = getFieldCount(%refreshList);
for (%i = 0; %i < %retCount; %i++)
{
%existingEntry = getField(%refreshList, %i);
%newRate = %existingEntry;
if (%existingEntry $= %oldRate)
break;
}
OptionsMenuSettingsList.setOptions(5, %refreshList);
OptionsMenuSettingsList.selectOption(5, %newRate);
}