optionsMenu.tscript 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458
  1. //options settings
  2. //Screen and Display menu
  3. //Renderer Mode
  4. //Screen resolution
  5. //Windowed/fullscreen(borderless?)
  6. //VSync
  7. //Screen brightness
  8. //screen brightness
  9. //screen gamma
  10. //Lighting Menu
  11. //Shadow Distance(Distance shadows are drawn to. Also affects shadowmap slices)
  12. //Shadow Quality(Resolution of shadows rendered, setting to none disables dynamic shadows)
  13. //Soft Shadows(Whether shadow softening is used)
  14. //Shadow caching(If the lights enable it, shadow caching is activated)
  15. //Light Draw Distance(How far away lights are still drawn. Doesn't impact vector lights like the sun)
  16. //Mesh and Textures Menu
  17. //Draw distance(Overall draw distance) -slider
  18. //Object draw distance(Draw distance from small/unimportant objects) -slider
  19. //Mesh quality
  20. //Texture quality
  21. //Foliage draw distance
  22. //Terrain Quality
  23. //Decal Quality
  24. //Effects Menu
  25. //Parallax
  26. //HDR
  27. //Light shafts
  28. //Motion Blur
  29. //Depth of Field
  30. //SSAO
  31. //AA(ModelXAmount)[defualt is FXAA]
  32. //Anisotropic filtering
  33. //Keybinds
  34. //Camera
  35. //horizontal mouse sensitivity
  36. //vert mouse sensitivity
  37. //invert vertical
  38. //zoom mouse sensitivities(both horz/vert)
  39. //headbob
  40. //FOV
  41. $yesNoList = "No\tYes";
  42. $onOffList = "Off\tOn";
  43. $optionsEntryPad = 10;
  44. function OptionsMenu::onAdd(%this)
  45. {
  46. if(!isObject(%this.optionsCategories))
  47. {
  48. %this.optionsCategories = new ArrayObject();
  49. }
  50. if(!isObject(%this.unappliedChanges))
  51. {
  52. %this.unappliedChanges = new ArrayObject(OptionsMenuUnappliedChanges);
  53. }
  54. %this.currentCategory = "";
  55. callOnModules("populateOptionsMenuCategories", "Game");
  56. }
  57. function OptionsMenu::onWake(%this)
  58. {
  59. VideoSettingsList.clear();
  60. for(%i=0; %i < VideoSettingsGroup.getCount(); %i++)
  61. {
  62. %setting = VideoSettingsGroup.getObject(%i);
  63. echo(" OptionsMenu::onWake() - video: " @ %setting.class);
  64. if(%setting.class $= "SubOptionsGroup")
  65. {
  66. %entry = addOptionGroup();
  67. %entry.text = %setting.displayName;
  68. if(isObject(%entry))
  69. VideoSettingsList.add(%entry);
  70. for(%s=0; %s < %setting.getCount(); %s++)
  71. {
  72. %option = %setting.getObject(%s);
  73. %optionsEntry = addOptionEntry(%option);
  74. if(isObject(%optionsEntry))
  75. {
  76. %optionsEntry.resize(0, 0, VideoSettingsList.extent.x, %optionsEntry.extent.y);
  77. VideoSettingsList.add(%optionsEntry);
  78. }
  79. }
  80. }
  81. else if(%setting.class $= "OptionsSettings")
  82. {
  83. %optionsEntry = addOptionEntry(%option);
  84. if(isObject(%optionsEntry))
  85. {
  86. %optionsEntry.resize(0, 0, VideoSettingsList.extent.x, %optionsEntry.extent.y);
  87. VideoSettingsList.add(%optionsEntry);
  88. }
  89. }
  90. }
  91. $MenuList = VideoSettingsList;
  92. //Find our first non-group entry
  93. while($MenuList.getObject($MenuList.listPosition).class !$= OptionsListEntry && $MenuList.listPosition < $MenuList.getCount())
  94. {
  95. $MenuList.listPosition += 1;
  96. }
  97. }
  98. if(!isObject( OptionsMenuActionMap ) )
  99. {
  100. new ActionMap(OptionsMenuActionMap){};
  101. OptionsMenuActionMap.bind( keyboard, w, OptionMenuNavigatePrev );
  102. OptionsMenuActionMap.bind( keyboard, s, OptionMenuNavigateNext );
  103. OptionsMenuActionMap.bind( gamepad, yaxis, "D", "-0.23 0.23", OptionMenuStickNavigate );
  104. OptionsMenuActionMap.bind( gamepad, upov, OptionMenuNavigatePrev );
  105. OptionsMenuActionMap.bind( gamepad, dpov, OptionMenuNavigateNext );
  106. OptionsMenuActionMap.bind( keyboard, a, OptionMenuPrevSetting );
  107. OptionsMenuActionMap.bind( keyboard, d, OptionMenuNextSetting );
  108. OptionsMenuActionMap.bind( gamepad, xaxis, "D", "-0.23 0.23", OptionMenuStickChangeSetting );
  109. OptionsMenuActionMap.bind( gamepad, lpov, OptionMenuPrevSetting );
  110. OptionsMenuActionMap.bind( gamepad, lpov, OptionMenuNextSetting );
  111. //OptionsMenuActionMap.bind( keyboard, Enter, BaseUIActivateSelected );
  112. //OptionsMenuActionMap.bind( gamepad, btn_a, BaseUIActivateSelected );
  113. }
  114. function VideoSettingsList::syncGui(%this)
  115. {
  116. %this.callOnChildren("setHighlighted", false);
  117. %btn = %this.getObject(%this.listPosition);
  118. if(%btn.class $= "OptionsListEntry")
  119. %btn-->button.setHighlighted(true);
  120. }
  121. //
  122. function OptionMenuNavigatePrev(%val)
  123. {
  124. if(%val)
  125. {
  126. $MenuList.listPosition -= 1;
  127. while( $MenuList.listPosition >= 0 && $MenuList.getObject($MenuList.listPosition).class !$= OptionsListEntry)
  128. {
  129. $MenuList.listPosition -= 1;
  130. }
  131. if($MenuList.listPosition < 0)
  132. $MenuList.listPosition = 0;
  133. $MenuList.syncGUI();
  134. }
  135. }
  136. function OptionMenuNavigateNext(%val)
  137. {
  138. if(%val)
  139. {
  140. $MenuList.listPosition += 1;
  141. while($MenuList.listPosition < $MenuList.getCount() && $MenuList.getObject($MenuList.listPosition).class !$= OptionsListEntry)
  142. {
  143. $MenuList.listPosition += 1;
  144. }
  145. if($MenuList.listPosition >= $MenuList.getCount())
  146. $MenuList.listPosition = $MenuList.getCount()-1;
  147. $MenuList.syncGUI();
  148. }
  149. }
  150. function OptionMenuStickNavigate(%val)
  151. {
  152. if(%val == -1)
  153. BaseUINavigateNext(1);
  154. else if(%val == 1)
  155. mainMenuNavigateDown(1);
  156. }
  157. function OptionMenuPrevSetting(%val)
  158. {
  159. %option = $MenuList.getObject($MenuList.listPosition);
  160. echo("Option: " @ %option.className);
  161. %optionObject = %option.optionsObject;
  162. %currentOptionLevel = %optionObject.getObject(%option.currentOptionIndex);
  163. echo("Changed option: " @ %optionObject.optionName @ " to level: " @ %currentOptionLevel.displayName);
  164. /*$MenuList.listPosition -= 1;
  165. if($MenuList.listPosition < 0)
  166. $MenuList.listPosition = 0;*/
  167. $MenuList.syncGUI();
  168. }
  169. function OptionMenuNextSetting(%val)
  170. {
  171. %option = $MenuList.getObject($MenuList.listPosition);
  172. %optionObject = %option.optionsObject;
  173. %currentOptionLevel = %optionObject.getObject(%option.currentOptionIndex);
  174. echo("Changed option: " @ %optionObject.optionName @ " to level: " @ %currentOptionLevel.displayName);
  175. /*$MenuList.listPosition += 1;
  176. if($MenuList.listPosition >= $MenuList.getCount())
  177. $MenuList.listPosition = $MenuList.getCount()-1;*/
  178. $MenuList.syncGUI();
  179. }
  180. function OptionMenuStickChangeSetting(%val)
  181. {
  182. }
  183. //
  184. function OptionsMenu::onOpen(%this)
  185. {
  186. OptionsMenuCategoryList.clear();
  187. for(%i=0; %i < %this.optionsCategories.count(); %i++)
  188. {
  189. %catName = %this.optionsCategories.getKey(%i);
  190. %callback = %this.optionsCategories.getValue(%i);
  191. %newCatButton = new GuiButtonCtrl() {
  192. text = %catName;
  193. groupNum = "-1";
  194. buttonType = "PushButton";
  195. useMouseEvents = "0";
  196. position = "0 180";
  197. extent = "248 35";
  198. minExtent = "8 2";
  199. horizSizing = "right";
  200. vertSizing = "bottom";
  201. profile = "GuiMenuButtonProfile";
  202. visible = "1";
  203. active = "1";
  204. command = %callback;
  205. tooltipProfile = "GuiToolTipProfile";
  206. hovertime = "1000";
  207. isContainer = "0";
  208. canSave = "1";
  209. canSaveDynamicFields = "0";
  210. };
  211. OptionsMenuCategoryList.add(%newCatButton);
  212. }
  213. %this.unappliedChanges.empty();
  214. $pref::Video::displayDeviceId = "";
  215. OptionsMenuCategoryList.setAsActiveMenuList();
  216. $activeMenuButtonContainer-->button1.set("btn_back", "R", "Reset", "OptionsMenu.resetToDefaults();");
  217. $activeMenuButtonContainer-->button2.disable();
  218. $activeMenuButtonContainer-->button3.set("", "Space", "Apply", "OptionsMenu.apply();");
  219. $activeMenuButtonContainer-->button4.set("btn_a", "", "Select", "OptionsMenu.select();");
  220. $activeMenuButtonContainer-->button5.set("btn_b", "Escape", "Back", %this @ ".navigation.popPage();");
  221. }
  222. //We capitalize on the canClose test here, because we want to prompt for unapplied options changes before
  223. //backing out. So when the UINavigation test canClose, we can see if we have unapplied settings and prompt
  224. //that via the message box and return false.
  225. //This gives the user a chance to choose how they wish to proceed before we allow the
  226. //UINavigation to move away from the options menu
  227. function OptionsMenu::canClose(%this)
  228. {
  229. //Another special case is us catching the 'back/pop' action by just shifting from one
  230. //menu list to another. In this case, we check if we were on the settings list as our active MenuList
  231. //if so, then the back/pop just moves us to the Category list as our active and we inform the
  232. //UINavigation to not close the page
  233. if(OptionsMenuSettingsList.isActiveMenuList())
  234. {
  235. OptionsMenuCategoryList.setAsActiveMenuList();
  236. return false;
  237. }
  238. else
  239. {
  240. //Here, we're on the category list as our active, so we're actually trying to leae the page
  241. //If we have unapplied changes, we want to prompt about them before closing the page and navigating away
  242. //If we don't, then we can process the popPage as normal and let the OptionsMenu close
  243. if(%this.unappliedChanges.count() != 0)
  244. {
  245. MessageBoxOKCancel("Discard Changes?", "You have unapplied changes to your settings, do you wish to apply or discard them?",
  246. "OptionsMenu.apply(); MainMenuGUI.popPage();", "" @ %this @ ".unappliedChanges.empty(); " @ %this @ ".navigation.popPage();",
  247. "Apply", "Discard");
  248. return false;
  249. }
  250. }
  251. return true;
  252. }
  253. function OptionsMenu::onClose(%this)
  254. {
  255. }
  256. function OptionsMenuSettingsList::onAdd(%this)
  257. {
  258. }
  259. function OptionsMenuSettingsList::getOptionsList(%this, %index)
  260. {
  261. }
  262. function OptionsMenu::select(%this)
  263. {
  264. if(OptionsMenuCategoryList.isActiveMenuList())
  265. {
  266. OptionsMenuSettingsList.setAsActiveMenuList();
  267. }
  268. }
  269. function OptionsMenu::apply(%this)
  270. {
  271. //Now we run through our list of unapplied changes and... apply them.
  272. %hasKeybindChanges = false;
  273. %hasVideoChanges = false;
  274. %hasPostFXChanges = false;
  275. %hasAudioChanges = false;
  276. %hasGraphicsChanges = false;
  277. for(%i=0; %i < %this.unappliedChanges.count(); %i++)
  278. {
  279. %targetVar = %this.unappliedChanges.getKey(%i);
  280. %newValue = strReplace(%this.unappliedChanges.getValue(%i), "\"", "");
  281. //First, lets just check through our action map names, see if any match
  282. %wasKeybind = false;
  283. for(%am=0; %am < ActionMapGroup.getCount(); %am++)
  284. {
  285. %actionMap = ActionMapGroup.getObject(%am);
  286. if(%actionMap == GlobalActionMap.getId())
  287. continue;
  288. %actionMapName = %actionMap.getName();
  289. if(%actionMapName $= %targetVar)
  290. {
  291. %hasKeybindChanges = true;
  292. %wasKeybind = true;
  293. break;
  294. }
  295. }
  296. if(!%wasKeybind)
  297. {
  298. %sanitizedVar = strReplace(%targetVar, "[", "");
  299. %sanitizedVar = strReplace(%sanitizedVar, "]", "");
  300. %sanitizedVar = strReplace(%sanitizedVar, ",", "_");
  301. %currentValue = getVariable(%sanitizedVar);
  302. if(%currentValue !$= %newValue)
  303. {
  304. setVariable(%targetVar, %newValue);
  305. //now, lets check for special cases that need additional handling
  306. //for updates
  307. if ( %targetVar $= "$pref::Video::displayDevice" )
  308. {
  309. schedule(32, 0, "MessageBoxOK", "Change requires restart", "Please restart the game for a display device change to take effect.");
  310. }
  311. else if(startsWith(%targetVar, "$pref::PostFX::"))
  312. {
  313. %hasPostFXChanges = true;
  314. }
  315. else if(startsWith(%targetVar, "$pref::Video::"))
  316. {
  317. %hasVideoChanges = true;
  318. //if it's the resolution, it's possible we got the human-friendly
  319. //version stored off. if so, reprocess into the usable state
  320. if(%targetVar $= "$pref::Video::Resolution")
  321. {
  322. if(strpos(%newValue, " x ") != -1)
  323. {
  324. %newValue = strreplace(%newValue, " x ", " ");
  325. setVariable(%targetVar, %newValue);
  326. }
  327. }
  328. //This is a bit of hackery to have an intermediate variable because we display in text
  329. //but save by index, so we take the applied name and get the index of the deviceId
  330. else if(%targetVar $= "$pref::Video::displayDeviceId")
  331. {
  332. %deviceId = getDisplayDeviceId($pref::Video::displayDeviceId);
  333. if(%deviceId == -1)
  334. %deviceId = 0;
  335. $pref::Video::deviceId = %deviceId;
  336. $pref::Video::displayDeviceId = "";
  337. }
  338. }
  339. else if(startsWith(%targetVar, "$pref::SFX::"))
  340. {
  341. %hasAudioChanges = true;
  342. }
  343. else if(startsWith(%targetVar, "$pref::Graphics::"))
  344. {
  345. %hasGraphicsChanges = true;
  346. }
  347. }
  348. }
  349. }
  350. //If we had keybind changes, go ahead and save those out
  351. if(%hasKeybindChanges)
  352. {
  353. %prefPath = getPrefpath();
  354. %actionMapCount = ActionMapGroup.getCount();
  355. %actionMapList = "";
  356. %append = false;
  357. for(%i=0; %i < %actionMapCount; %i++)
  358. {
  359. %actionMap = ActionMapGroup.getObject(%i);
  360. if(%actionMap == GlobalActionMap.getId())
  361. continue;
  362. %actionMap.save( %prefPath @ "/keybinds." @ $TorqueScriptFileExtension, %append );
  363. if(%append != true)
  364. %append = true;
  365. }
  366. }
  367. if(%hasPostFXChanges)
  368. {
  369. updatePostFXSettings();
  370. }
  371. if(%hasVideoChanges)
  372. {
  373. updateDisplaySettings();
  374. }
  375. if(%hasAudioChanges)
  376. {
  377. updateAudioSettings();
  378. }
  379. if(%hasGraphicsChanges)
  380. {
  381. updateGraphicsSettings();
  382. }
  383. //Finally, write our prefs to file
  384. %prefPath = getPrefpath();
  385. export("$pref::*", %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension, false);
  386. OptionsMenu.unappliedChanges.empty();
  387. }
  388. function OptionsMenu::resetToDefaults(%this)
  389. {
  390. MessageBoxOKCancel("", "This will set the graphical settings back to the auto-detected defaults. Do you wish to continue?", "AutodetectGraphics();", "");
  391. }
  392. function OptionsMenu::refresh(%this)
  393. {
  394. //cache our scroll position so we can ensure we end up back at it after the refresh
  395. %lastScrollPos = OptionsMenuSettingsScroll.getScrollPosition();
  396. %cat = %this.currentCategory;
  397. if(%this.currentCategory !$= "")
  398. {
  399. if(!isInt(%this.currentCategory))
  400. {
  401. %this.currentCategory = getOptionsCategoryIndexByName(%this.currentCategory);
  402. }
  403. if(%this.currentCategory == -1)
  404. return;
  405. %category = %this.optionsCategories.getKey(%this.currentCategory);
  406. %command = %this.optionsCategories.getValue(%this.currentCategory);
  407. eval(%command);
  408. }
  409. //now, because we reconstruct the displayed set, we'll force the mouse(if we're using it as our input)
  410. //to be poked so we can re-track to whatever control, if any, we're over
  411. if($activeControllerType !$= "gamepad")
  412. {
  413. Canvas.setCursorPos(Canvas.getCursorPos());
  414. }
  415. //restore scroll position
  416. OptionsMenuSettingsScroll.setScrollPosition(%lastScrollPos.x, %lastScrollPos.y);
  417. }
  418. function OptionsMenu::getOptionVariableValue(%this, %variableName)
  419. {
  420. %unappliedPrefIndex = %this.unappliedChanges.getIndexFromKey(%variableName);
  421. if(%unappliedPrefIndex != -1)
  422. {
  423. %value = %this.unappliedChanges.getValue(%unappliedPrefIndex);
  424. return strreplace(%value, "\"", "");
  425. }
  426. %sanitizedVar = strReplace(%variableName, "[", "");
  427. %sanitizedVar = strReplace(%sanitizedVar, "]", "");
  428. %sanitizedVar = strReplace(%sanitizedVar, ",", "_");
  429. return getVariable(%sanitizedVar);
  430. }
  431. function OptionsMenuSelectButton::onVisible(%this, %state)
  432. {
  433. //We're sorta cheating here.
  434. //This button should only be displayed when we're in the categories list
  435. //so whenever the status changes, such as automatically refreshing due to
  436. //navigation events, we'll just do a quick check to ensure we're
  437. //in the right visibility mode
  438. if(%state && OptionsMenuSettingsList.isActiveMenuList())
  439. {
  440. %this.setHidden(true);
  441. }
  442. }
  443. //
  444. //
  445. //
  446. function populateDisplaySettingsList()
  447. {
  448. OptionsMenuSettingsList.clear();
  449. OptionsMenu.currentCategory = "Display";
  450. if(isObject(OptionName))
  451. OptionName.setText("");
  452. if(isObject(OptionDescription))
  453. OptionDescription.setText("");
  454. %apiList = "";
  455. %apiCount = GFXInit::getAdapterCount();
  456. %apiIdx = 0;
  457. for(%i=0; %i < %apiCount; %i++)
  458. {
  459. %api = GFXInit::getAdapterType(%i);
  460. if(%api !$= "NullDevice")
  461. {
  462. if(%apiIdx==0)
  463. %apiList = %api;
  464. else
  465. %apiList = %apiList TAB %api;
  466. %apiIdx++;
  467. }
  468. }
  469. trim(%apiList);
  470. %displayDevice = OptionsMenu.getOptionVariableValue("$pref::Video::displayDevice");
  471. if(%displayDevice $= "")
  472. %displayDevice = getDisplayDeviceType();
  473. OptionsMenuSettingsList.addOptionRow("Display API", "$pref::Video::displayDevice", %apiList, false, "", true, "The display API used for rendering.", %displayDevice);
  474. %numDevices = Canvas.getMonitorCount();
  475. %devicesList = getDisplayDeviceList();
  476. if($pref::Video::displayDeviceId $= "")
  477. $pref::Video::displayDeviceId = getField(%devicesList, $pref::Video::deviceId);
  478. OptionsMenuSettingsList.addOptionRow("Display Device", "$pref::Video::displayDeviceId", %devicesList, false, "", true, "The display devices the window should be on.");
  479. if (%numDevices > 1)
  480. OptionsMenuSettingsList.setRowEnabled(1, true);
  481. else
  482. OptionsMenuSettingsList.setRowEnabled(1, false);
  483. %mode = OptionsMenu.getOptionVariableValue("$pref::Video::deviceMode");
  484. if(isInt(%mode))
  485. %mode = getField($Video::ModeTags, $pref::Video::deviceMode);
  486. OptionsMenuSettingsList.addOptionRow("Window Mode", "$pref::Video::deviceMode", $Video::ModeTags, false, "", true, "", %mode);
  487. if(%mode !$= "Borderless")
  488. {
  489. %resolutionList = getScreenResolutionList($pref::Video::deviceId, $Video::Mode[%mode]);
  490. %resolution = OptionsMenu.getOptionVariableValue("$pref::Video::Resolution");
  491. if(%resolution $= "")
  492. %resolution = $pref::Video::mode;
  493. %resolution = _makePrettyResString(%resolution);
  494. OptionsMenuSettingsList.addOptionRow("Resolution", "$pref::Video::Resolution", %resolutionList, false, "", true, "Resolution of the game window", %resolution);
  495. // If the requested resolution could not be set, mark the control and pref as changed.
  496. %resControl = OptionsMenuSettingsList.getObject(OptionsMenuSettingsList.getCount()-1);
  497. if (%resControl.getCurrentOption() !$= %resolution)
  498. %resControl.onChange();
  499. }
  500. OptionsMenuSettingsList.addOptionBoolRow("VSync", "$pref::Video::enableVerticalSync", $YesNoList, false, "", true, "", "");
  501. %refreshList = getScreenRefreshList($pref::Video::mode);
  502. OptionsMenuSettingsList.addOptionRow("Refresh Rate", "$pref::Video::RefreshRate", %refreshList, false, "", true, "", OptionsMenu.getOptionVariableValue("$pref::Video::RefreshRate"));
  503. //move to gameplay tab
  504. //OptionsMenuSettingsList.addSliderRow("Field of View", "", 75, 5, "65 100", "");
  505. //OptionsMenuSettingsList.addSliderRow("Brightness", "", 0.5, 0.1, "0 1", "");
  506. //OptionsMenuSettingsList.addSliderRow("Contrast", "", 0.5, 0.1, "0 1", "");
  507. }
  508. //
  509. //
  510. //
  511. function populateGraphicsSettingsList()
  512. {
  513. OptionsMenuSettingsList.clear();
  514. OptionsMenu.currentCategory = "Graphics";
  515. if(isObject(OptionName))
  516. OptionName.setText("");
  517. if(isObject(OptionDescription))
  518. OptionDescription.setText("");
  519. %yesNoList = "No\tYes";
  520. %onOffList = "Off\tOn";
  521. %anisoFilter = "Off\t4\t8\t16";
  522. %aaTypeFilter = "None\tFXAA\tSMAA\tSMAA High";
  523. OptionsMenuSettingsList.addOptionQualityLevelRow("Lighting Quality", "$pref::Graphics::LightingQuality",
  524. LightingQualityList, false, "", true, "Amount and drawdistance of local lights");
  525. OptionsMenuSettingsList.addOptionQualityLevelRow("Shadow Quality", "$pref::Graphics::ShadowQuality",
  526. ShadowQualityList, false, "", true, "Shadow revolution quality");
  527. %shadowQuality = OptionsMenu.getOptionVariableValue("$pref::Graphics::ShadowQuality");
  528. if(%shadowQuality !$= "None")
  529. {
  530. OptionsMenuSettingsList.addOptionQualityLevelRow("Soft Shadow Quality", "$pref::Graphics::SoftShadowQuality",
  531. SoftShadowList, false, "", true, "Amount of softening applied to shadowmaps");
  532. }
  533. OptionsMenuSettingsList.addOptionQualityLevelRow("Mesh Quality", "$pref::Graphics::MeshQuality",
  534. MeshQualityGroup, false, "", true, "Fidelity of rendering of mesh objects");
  535. OptionsMenuSettingsList.addOptionQualityLevelRow("Object Draw Distance", "$pref::Graphics::ObjectDrawDistance",
  536. MeshDrawDistQualityGroup, false, "", true, "Dictates if and when static objects fade out in the distance");
  537. OptionsMenuSettingsList.addOptionQualityLevelRow("Texture Quality", "$pref::Graphics::TextureQuality",
  538. TextureQualityGroup, false, "", true, "Fidelity of textures");
  539. OptionsMenuSettingsList.addOptionQualityLevelRow("Terrain Quality", "$pref::Graphics::TerrainQuality",
  540. TerrainQualityGroup, false, "", true, "Quality level of terrain objects");
  541. OptionsMenuSettingsList.addOptionQualityLevelRow("Decal Lifetime", "$pref::Graphics::DecalLifetime",
  542. DecalLifetimeGroup, false, "", true, "How long decals are rendered");
  543. OptionsMenuSettingsList.addOptionQualityLevelRow("Ground Cover Density", "$pref::Graphics::GroundCoverDensity",
  544. GroundCoverDensityGroup, false, "", true, "Density of ground cover items, such as grass");
  545. OptionsMenuSettingsList.addOptionQualityLevelRow("Shader Quality", "$pref::Graphics::ShaderQuality",
  546. ShaderQualityGroup, false, "", true, "Dictates the overall shader quality level, adjusting what features are enabled.");
  547. OptionsMenuSettingsList.addOptionRow("Anisotropic Filtering", "$pref::Video::defaultAnisotropy", %anisoFilter, false, "", true, "Amount of Anisotropic Filtering on textures, which dictates their sharpness at a distance");
  548. OptionsMenuSettingsList.addOptionRow("Anti-Aliasing Type", "$pref::Video::AAMode", %aaTypeFilter, false, "", true, "The Anti-Aliasing Method applied to rendering");
  549. OptionsMenuSettingsList.addOptionBoolRow("Parallax", "$pref::Video::enableParallaxMapping", %onOffList, false, "", true, "Whether the surface parallax shader effect is enabled", "");
  550. OptionsMenuSettingsList.addOptionBoolRow("Water Reflections", "$pref::Water::enableTrueReflections", %onOffList, false, "", true, "Whether water reflections are enabled", "");
  551. OptionsMenuSettingsList.addOptionBoolRow("SSAO", "$pref::PostFX::EnableSSAO", %onOffList, false, "", true, "Whether Screen-Space Ambient Occlusion is enabled");
  552. OptionsMenuSettingsList.addOptionBoolRow("Depth of Field", "$pref::PostFX::EnableDOF", %onOffList, false, "", true, "Whether the Depth of Field effect is enabled");
  553. OptionsMenuSettingsList.addOptionBoolRow("Vignette", "$pref::PostFX::EnableVignette", %onOffList, false, "", true, "Whether the vignette effect is enabled");
  554. OptionsMenuSettingsList.addOptionBoolRow("Light Rays", "$pref::PostFX::EnableLightRays", %onOffList, false, "", true, "Whether the light rays effect is enabled");
  555. }
  556. function updateGraphicsSettings()
  557. {
  558. if($pref::Graphics::LightingQuality !$= getCurrentQualityLevel(LightingQualityList))
  559. LightingQualityList.applySetting($pref::Graphics::LightingQuality);
  560. if($pref::Graphics::ShadowQuality !$= getCurrentQualityLevel(ShadowQualityList))
  561. ShadowQualityList.applySetting($pref::Graphics::ShadowQuality);
  562. if($pref::Graphics::SoftShadowQuality !$= getCurrentQualityLevel(SoftShadowList))
  563. SoftShadowList.applySetting($pref::Graphics::SoftShadowQuality);
  564. if($pref::Graphics::MeshQuality !$= getCurrentQualityLevel(MeshQualityGroup))
  565. MeshQualityGroup.applySetting($pref::Graphics::MeshQuality);
  566. if($pref::Graphics::ObjectDrawDistance !$= getCurrentQualityLevel(MeshDrawDistQualityGroup))
  567. MeshDrawDistQualityGroup.applySetting($pref::Graphics::ObjectDrawDistance);
  568. if($pref::Graphics::TextureQuality !$= getCurrentQualityLevel(TextureQualityGroup))
  569. {
  570. TextureQualityGroup.applySetting($pref::Graphics::TextureQuality);
  571. reloadTextures();
  572. }
  573. if($pref::Graphics::TerrainQuality !$= getCurrentQualityLevel(TerrainQualityGroup))
  574. TerrainQualityGroup.applySetting($pref::Graphics::TerrainQuality);
  575. if($pref::Graphics::DecalLifetime !$= getCurrentQualityLevel(DecalLifetimeGroup))
  576. DecalLifetimeGroup.applySetting($pref::Graphics::DecalLifetime);
  577. if($pref::Graphics::GroundCoverDensity !$= getCurrentQualityLevel(GroundCoverDensityGroup))
  578. GroundCoverDensityGroup.applySetting($pref::Graphics::GroundCoverDensity);
  579. if($pref::Graphics::ShaderQuality !$= getCurrentQualityLevel(ShaderQualityGroup))
  580. {
  581. ShaderQualityGroup.applySetting($pref::Graphics::ShaderQuality);
  582. //this has ties into postFX behaviors, so we'll force an update to it here
  583. updatePostFXSettings();
  584. }
  585. }
  586. function updateDisplaySettings()
  587. {
  588. //Update the display settings now
  589. %deviceName = getDisplayDeviceName();
  590. %newDeviceID = getWord(%deviceName, 0) - 1;
  591. if(!isInt($pref::Video::deviceMode))
  592. {
  593. //probably saved out as the mode name, so just translate it back
  594. for(%i=0; %i < getFieldCount($Video::ModeTags); %i++)
  595. {
  596. if(getField($Video::ModeTags, %i) $= $pref::Video::deviceMode)
  597. {
  598. $pref::Video::deviceMode = %i;
  599. break;
  600. }
  601. }
  602. }
  603. %deviceModeName = getField($Video::ModeTags, $pref::Video::deviceMode);
  604. %newDeviceMode = 0;
  605. foreach$(%modeName in $Video::ModeTags)
  606. {
  607. if (%deviceModeName $= %modeName)
  608. break;
  609. else
  610. %newDeviceMode++;
  611. }
  612. if($pref::Video::deviceMode == $Video::ModeBorderless)
  613. {
  614. //if we're changing to borderless, we swap to the full resolution of the desktop
  615. $pref::Video::mode = Canvas.getBestCanvasRes($pref::Video::deviceId, $pref::Video::deviceMode);
  616. $pref::Video::Resolution = $pref::Video::mode.x SPC $pref::Video::mode.y;
  617. }
  618. %newRes = $pref::Video::Resolution;
  619. %newBpp = 32; // ... its not 1997 anymore.
  620. %newFullScreen = %deviceModeName $= "Fullscreen" ? true : false;
  621. %newRefresh = $pref::Video::RefreshRate;
  622. %newVsync = $pref::Video::enableVerticalSync;
  623. %newAA = $pref::Video::AA;
  624. // Build the final mode string.
  625. %newMode = $pref::Video::Resolution SPC %newFullScreen SPC %newBpp SPC %newRefresh SPC %newAA;
  626. // Change the video mode.
  627. if ( %newMode !$= $pref::Video::mode || %newDeviceID != $pref::Video::deviceId ||
  628. %newVsync != $pref::Video::enableVerticalSync || %newDeviceMode != $pref::Video::deviceMode)
  629. {
  630. //****Edge Case Hack
  631. // If we're in fullscreen mode and switching to a different monitor at the
  632. // same resolution and maintaining fullscreen, GFX...WindowTarget::resetMode()
  633. // will early-out because there is no "mode change" and the monitor change
  634. // will not get applied. Instead of modifying platform code, we're going to
  635. // move onto the new monitor in borderless and immediately switch to FS.
  636. if (%newFullScreen && $pref::Video::FullScreen &&
  637. ($pref::Video::Resolution $= %newRes) && ($pref::Video::deviceId != %newDeviceID))
  638. {
  639. $pref::Video::deviceId = %newDeviceID;
  640. $pref::Video::deviceMode = $Video::ModeBorderless;
  641. %tmpModeStr = Canvas.getMonitorMode(%newDeviceID, 0);
  642. Canvas.setVideoMode(%tmpModeStr.x, %tmpModeStr.y, false, 32, getWord(%tmpModeStr, $WORD::REFRESH), %newAA);
  643. }
  644. $pref::Video::mode = %newMode;
  645. $pref::Video::enableVerticalSync = %newVsync;
  646. $pref::Video::deviceId = %newDeviceID;
  647. $pref::Video::deviceMode = %newDeviceMode;
  648. $pref::Video::Resolution = %newRes;
  649. $pref::Video::FullScreen = %newFullScreen;
  650. $pref::Video::RefreshRate = %newRefresh;
  651. $pref::Video::AA = %newAA;
  652. configureCanvas();
  653. }
  654. }
  655. function updatePostFXSettings()
  656. {
  657. PostFXManager.settingsEffectSetEnabled(SSAOPostFx, $pref::PostFX::EnableSSAO);
  658. PostFXManager.settingsEffectSetEnabled(DepthOfFieldPostFX, $pref::PostFX::EnableDOF);
  659. PostFXManager.settingsEffectSetEnabled(LightRayPostFX, $pref::PostFX::EnableLightRays);
  660. PostFXManager.settingsEffectSetEnabled(vignettePostFX, $pref::PostFX::EnableVignette);
  661. }
  662. //
  663. //
  664. //
  665. function populateAudioSettingsList()
  666. {
  667. OptionsMenuSettingsList.clear();
  668. OptionsMenu.currentCategory = "Audio";
  669. if(isObject(OptionName))
  670. OptionName.setText("");
  671. if(isObject(OptionDescription))
  672. OptionDescription.setText("");
  673. %buffer = sfxGetAvailableDevices();
  674. %count = getRecordCount( %buffer );
  675. %audioDriverList = "";
  676. %audioProviderList = "";
  677. %audioDeviceList = "";
  678. $currentAudioProvider = $currentAudioProvider $= "" ? $pref::SFX::provider : $currentAudioProvider;
  679. for(%i = 0; %i < %count; %i++)
  680. {
  681. %record = getRecord(%buffer, %i);
  682. %provider = getField(%record, 0);
  683. %device = getField(%record, 1);
  684. //When the client is actually running, we don't care about null audo devices
  685. if(%provider $= "null")
  686. continue;
  687. if(%audioProviderList $= "")
  688. %audioProviderList = %provider;
  689. else
  690. %audioProviderList = %audioProviderList @ "\t" @ %provider;
  691. if(%provider $= $currentAudioProvider)
  692. {
  693. if(%audioDeviceList $= "")
  694. %audioDeviceList = %device;
  695. else
  696. %audioDeviceList = %audioDeviceList @ "\t" @ %device;
  697. }
  698. }
  699. OptionsMenuSettingsList.addOptionRow("Audio Provider", "$pref::SFX::provider", %audioProviderList, false, "audioProviderChanged", true, "");
  700. OptionsMenuSettingsList.addOptionRow("Audio Device", "$pref::SFX::device", %audioDeviceList, false, "", true);
  701. OptionsMenuSettingsList.addSliderRow("Master Volume", "$pref::SFX::masterVolume", 0.1, "0 1", "");
  702. OptionsMenuSettingsList.addSliderRow("GUI Volume", "$pref::SFX::channelVolume[" @ $GuiAudioType @ "]", 0.1, "0 1", "");
  703. OptionsMenuSettingsList.addSliderRow("Effects Volume", "$pref::SFX::channelVolume[" @ $SimAudioType @ "]", 0.1, "0 1", "");
  704. OptionsMenuSettingsList.addSliderRow("Music Volume", "$pref::SFX::channelVolume[" @ $MusicAudioType @ "]", 0.1, "0 1", "");
  705. }
  706. function audioProviderChanged()
  707. {
  708. //Get the option we have set for the provider
  709. %provider = OptionsMenuSettingsList.getCurrentOption(0);
  710. $currentAudioProvider = %provider;
  711. //And now refresh the list to get the correct devices
  712. populateAudioSettingsList();
  713. }
  714. function updateAudioSettings()
  715. {
  716. //$pref::SFX::masterVolume = OptionsMenuSettingsList.getValue(2);
  717. sfxSetMasterVolume( $pref::SFX::masterVolume );
  718. //$pref::SFX::channelVolume[ $GuiAudioType ] = OptionsMenuSettingsList.getValue(3);
  719. //$pref::SFX::channelVolume[ $SimAudioType ] = OptionsMenuSettingsList.getValue(4);
  720. //$pref::SFX::channelVolume[ $MusicAudioType ] = OptionsMenuSettingsList.getValue(5);
  721. sfxSetChannelVolume( $GuiAudioType, $pref::SFX::channelVolume[ $GuiAudioType ] );
  722. sfxSetChannelVolume( $SimAudioType, $pref::SFX::channelVolume[ $SimAudioType ] );
  723. sfxSetChannelVolume( $MusicAudioType, $pref::SFX::channelVolume[ $MusicAudioType ] );
  724. //$pref::SFX::provider = OptionsMenuSettingsList.getCurrentOption(0);
  725. //$pref::SFX::device = OptionsMenuSettingsList.getCurrentOption(1);
  726. if ( !sfxCreateDevice( $pref::SFX::provider,
  727. $pref::SFX::device,
  728. $pref::SFX::useHardware,
  729. -1 ) )
  730. error( "Unable to create SFX device: " @ $pref::SFX::provider
  731. SPC $pref::SFX::device
  732. SPC $pref::SFX::useHardware );
  733. if( !isObject( $AudioTestHandle ) )
  734. {
  735. sfxPlay(menuButtonPressed);
  736. }
  737. }
  738. //
  739. //
  740. //
  741. function populateKeyboardMouseSettingsList()
  742. {
  743. OptionsMenuSettingsList.clear();
  744. OptionsMenu.currentCategory = "Keyboard & Mouse";
  745. if(isObject(OptionName))
  746. OptionName.setText("");
  747. if(isObject(OptionDescription))
  748. OptionDescription.setText("");
  749. $remapListDevice = "keyboard";
  750. fillRemapList();
  751. //OptionsMenuSettingsList.refresh();
  752. }
  753. function populateGamepadSettingsList()
  754. {
  755. OptionsMenuSettingsList.clear();
  756. OptionsMenu.currentCategory = "Gamepad";
  757. if(isObject(OptionName))
  758. OptionName.setText("");
  759. if(isObject(OptionDescription))
  760. OptionDescription.setText("");
  761. $remapListDevice = "gamepad";
  762. fillRemapList();
  763. OptionsMenuSettingsList.updateStack();
  764. }
  765. //
  766. //
  767. //
  768. function getDisplayDeviceList()
  769. {
  770. %numDevices = Canvas.getMonitorCount();
  771. %devicesList = "";
  772. for(%i = 0; %i < %numDevices; %i++)
  773. {
  774. %device = (%i+1) @ " - " @ Canvas.getMonitorName(%i);
  775. if(%i==0)
  776. %devicesList = %device;
  777. else
  778. %devicesList = %devicesList @ "\t" @ %device;
  779. }
  780. return %devicesList;
  781. }
  782. function getDisplayDeviceId(%displayDeviceName)
  783. {
  784. %deviceList = getDisplayDeviceList();
  785. %deviceCount = getFieldCount(%deviceList);
  786. for(%d = 0; %d < %deviceCount; %d++)
  787. {
  788. %deviceName = getField(%deviceList, %d);
  789. if(%deviceName $= %displayDeviceName)
  790. return %d;
  791. }
  792. return -1;
  793. }
  794. //
  795. //
  796. //
  797. function OptionsMenuList::activateRow(%this)
  798. {
  799. //OptionsMenuSettingsList.setFirstResponder();
  800. OptionsMenuSettingsList.setAsActiveMenuList();
  801. }
  802. function OptionsMenuSettingsList::setRowEnabled(%this, %row, %status)
  803. {
  804. %option = %this.getObject(%row);
  805. if(isObject(%option))
  806. {
  807. %option.setEnabled(%status);
  808. }
  809. }
  810. function OptionsMenuSettingsList::addOptionRow(%this, %label, %targetPrefVar, %optionsList, %wrapOptions, %callback, %enabled, %description, %defaultValue)
  811. {
  812. if(%enabled $= "")
  813. %enabled = true;
  814. %optionsRowSize = 30;
  815. %optionColumnWidth = %this.extent.x * 0.5;//todo, calculate off longest option text?
  816. %option = new GuiGameSettingsCtrl() {
  817. class = "MenuOptionsButton";
  818. profile = "GuiMenuButtonProfile";
  819. horizSizing = "width";
  820. vertSizing = "bottom";
  821. position = "0 0";
  822. extent = %this.extent.x SPC %optionsRowSize;
  823. columnSplit = %optionColumnWidth;
  824. useMouseEvents = true;
  825. previousBitmapAsset = "UI:previousOption_n_image";
  826. nextBitmapAsset = "UI:nextOption_n_image";
  827. };
  828. %option.targetPrefVar = %targetPrefVar; //create a var-option association
  829. if(%defaultValue $= "")
  830. {
  831. %unappliedPrefIndex = OptionsMenu.unappliedChanges.getIndexFromKey(%targetPrefVar);
  832. if(%unappliedPrefIndex != -1)
  833. {
  834. %value = OptionsMenu.unappliedChanges.getValue(%unappliedPrefIndex);
  835. %defaultValue = strreplace(%value, "\"", "");
  836. }
  837. if(%defaultValue $= "")
  838. {
  839. %sanitizedVar = strReplace(%targetPrefVar, "[", "");
  840. %sanitizedVar = strReplace(%sanitizedVar, "]", "");
  841. %sanitizedVar = strReplace(%sanitizedVar, ",", "_");
  842. %defaultValue = getVariable(%sanitizedVar);
  843. }
  844. }
  845. /*if(%defaultValue $= "Off" || %defaultValue $= "No")
  846. %defaultValue = "0";
  847. if(%defaultValue $= "On" || %defaultValue $= "Yes")
  848. %defaultValue = "1";*/
  849. %option.setListSetting(%label, %optionsList, %wrapOptions, %callback, %enabled, %description, %defaultValue);
  850. %this.add(%option);
  851. }
  852. function OptionsMenuSettingsList::addOptionQualityLevelRow(%this, %label, %targetPrefVar, %qualityLevelList, %wrapOptions, %callback, %enabled, %description, %defaultValue)
  853. {
  854. if(%defaultValue $= "")
  855. {
  856. %unappliedPrefIndex = OptionsMenu.unappliedChanges.getIndexFromKey(%targetPrefVar);
  857. if(%unappliedPrefIndex != -1)
  858. {
  859. %value = OptionsMenu.unappliedChanges.getValue(%unappliedPrefIndex);
  860. %defaultValue = strreplace(%value, "\"", "");
  861. }
  862. if(%defaultValue $= "")
  863. {
  864. %sanitizedVar = strReplace(%targetPrefVar, "[", "");
  865. %sanitizedVar = strReplace(%sanitizedVar, "]", "");
  866. %sanitizedVar = strReplace(%sanitizedVar, ",", "_");
  867. %defaultValue = getVariable(%sanitizedVar);
  868. }
  869. if(%defaultValue $= "")
  870. %defaultValue = getCurrentQualityLevel(%qualityLevelList);
  871. }
  872. return %this.addOptionRow(%label, %targetPrefVar, getQualityLevels(%qualityLevelList),
  873. %wrapOptions, %callback, %enabled, %description, %defaultValue);
  874. }
  875. function OptionsMenuSettingsList::addOptionBoolRow(%this, %label, %targetPrefVar, %qualityLevelList, %wrapOptions, %callback, %enabled, %description, %defaultValue, %inverted)
  876. {
  877. if(%defaultValue $= "")
  878. %defaultValue = OptionsMenu.getOptionVariableValue(%targetPrefVar);
  879. if(%inverted $= "")
  880. %inverted = false;
  881. //Lame and hacky, but some variables are 'disabled' and some are 'enabled'
  882. if(isInt(%defaultValue) && %inverted)
  883. {
  884. if(%defaultValue == 0)
  885. %defaultValue = 1;
  886. else
  887. %defaultValue = 0;
  888. }
  889. if(%qualityLevelList $= $yesNoList && isInt(%defaultValue))
  890. {
  891. %defaultValue = convertBoolToYesNo(%defaultValue);
  892. }
  893. else if(%qualityLevelList $= $onOffList && isInt(%defaultValue))
  894. {
  895. %defaultValue = convertBoolToOnOff(%defaultValue);
  896. }
  897. return %this.addOptionRow(%label, %targetPrefVar, %qualityLevelList,
  898. %wrapOptions, %callback, %enabled, %description, %defaultValue);
  899. }
  900. function OptionsMenuSettingsList::addSliderRow(%this, %label, %targetPrefVar, %increment, %range, %callback, %enabled, %description, %defaultValue)
  901. {
  902. if(%enabled $= "")
  903. %enabled = true;
  904. %optionsRowSize = 30;
  905. %optionColumnWidth = %this.extent.x * 0.5;//todo, calculate off longest option text?
  906. %option = new GuiGameSettingsCtrl() {
  907. class = "MenuOptionsButton";
  908. profile = "GuiMenuButtonProfile";
  909. horizSizing = "width";
  910. vertSizing = "bottom";
  911. position = "0 0";
  912. extent = %this.extent.x SPC %optionsRowSize;
  913. columnSplit = %optionColumnWidth;
  914. useMouseEvents = true;
  915. };
  916. %option.targetPrefVar = %targetPrefVar; //create a var-option association
  917. if(%defaultValue $= "")
  918. %defaultValue = OptionsMenu.getOptionVariableValue(%targetPrefVar);
  919. %option.setSliderSetting(%label, %defaultValue, %increment, %range, %callback, %enabled, %description);
  920. %this.add(%option);
  921. }
  922. function OptionsMenuSettingsList::addKeybindRow(%this, %label, %bitmapName, %callback, %enabled, %description, %remapIndex)
  923. {
  924. if(%enabled $= "")
  925. %enabled = true;
  926. %optionsRowSize = 40;
  927. %optionColumnWidth = %this.extent.x * 0.5;//todo, calculate off longest option text?
  928. %option = new GuiGameSettingsCtrl() {
  929. class = "MenuOptionsButton";
  930. profile = "GuiMenuButtonProfile";
  931. horizSizing = "width";
  932. vertSizing = "bottom";
  933. position = "0 0";
  934. extent = %this.extent.x SPC %optionsRowSize;
  935. columnSplit = %optionColumnWidth;
  936. useMouseEvents = true;
  937. };
  938. %option.remapIndex = %remapIndex;
  939. %option.setKeybindSetting(%label, %bitmapName, %callback, %enabled, %description);
  940. %this.add(%option);
  941. }
  942. //
  943. function OptionsMenuCategoryList::onNavigate(%this, %index)
  944. {
  945. OptionsMenu.currentCategory = %index;
  946. %this.getObject(%index).performClick();
  947. }
  948. function convertOptionToBool(%val)
  949. {
  950. if(%val $= "yes" || %val $= "on")
  951. return 1;
  952. else
  953. return 0;
  954. }
  955. function convertBoolToYesNo(%val)
  956. {
  957. if(%val == 1)
  958. return "Yes";
  959. else if(%val == 0)
  960. return "No";
  961. return %val;
  962. }
  963. function convertBoolToOnOff(%val)
  964. {
  965. if(%val == 1)
  966. return "On";
  967. else if(%val == 0)
  968. return "Off";
  969. return %val;
  970. }
  971. function getDisplayDeviceName()
  972. {
  973. %numDevices = Canvas.getMonitorCount();
  974. %devicesList = "";
  975. for(%i = 0; %i < %numDevices; %i++)
  976. {
  977. %device = (%i+1) @ " - " @ Canvas.getMonitorName(%i);
  978. if(%i==0)
  979. %devicesList = %device;
  980. else
  981. %devicesList = %devicesList @ "\t" @ %device;
  982. }
  983. return getField(%devicesList, $pref::Video::deviceId);
  984. }
  985. //
  986. //
  987. //
  988. function MenuOptionsButton::onMouseEnter(%this)
  989. {
  990. if(isObject(OptionName))
  991. OptionName.setText(%this.getLabel());
  992. if(isObject(OptionDescription))
  993. OptionDescription.setText(%this.getToolTip());
  994. }
  995. function MenuOptionsButton::onMouseLeave(%this)
  996. {
  997. if(isObject(OptionName))
  998. OptionName.setText("");
  999. if(isObject(OptionDescription))
  1000. OptionDescription.setText("");
  1001. }
  1002. function MenuOptionsButton::onHighlighted(%this, %state)
  1003. {
  1004. MenuListButton::onHighlighted(%this, %state);
  1005. }
  1006. function MenuOptionsButton::onChange(%this)
  1007. {
  1008. %optionMode = %this.getMode();
  1009. %optionName = %this.getLabel();
  1010. %tooltipText = %this.getTooltip();
  1011. %targetVar = %this.targetPrefVar;
  1012. OptionName.setText(%optionName);
  1013. OptionDescription.setText(%tooltipText);
  1014. if(%optionMode == 0)
  1015. {
  1016. %currentValue = %this.getCurrentOption();
  1017. if(%currentValue !$= "")
  1018. {
  1019. if(%currentValue $= "yes" || %currentValue $= "on")
  1020. %saveReadyValue = 1;
  1021. else if(%currentValue $= "no" || %currentValue $= "off")
  1022. %saveReadyValue = 0;
  1023. else
  1024. %saveReadyValue = %currentValue;
  1025. %prefIndex = OptionsMenu.unappliedChanges.getIndexFromKey(%targetVar);
  1026. if(%prefIndex == -1)
  1027. {
  1028. echo("Setting UnappliedChanges via add: key:" @ %targetVar @", value: " @ %saveReadyValue);
  1029. OptionsMenu.unappliedChanges.add(%targetVar, "\"" @ %saveReadyValue @ "\"" );
  1030. }
  1031. else
  1032. {
  1033. echo("Setting UnappliedChanges via modify: key:" @ %targetVar @", value: " @ %saveReadyValue);
  1034. OptionsMenu.unappliedChanges.setValue("\"" @ %saveReadyValue @ "\"", %prefIndex);
  1035. }
  1036. }
  1037. }
  1038. else if(%optionMode == 1)
  1039. {
  1040. %currentValue = %this.getValue();
  1041. %prefIndex = OptionsMenu.unappliedChanges.getIndexFromKey(%targetVar);
  1042. if(%prefIndex == -1)
  1043. {
  1044. echo("Setting UnappliedChanges via add: key:" @ %targetVar @", value: " @ %currentValue);
  1045. OptionsMenu.unappliedChanges.add(%targetVar, "\"" @ %currentValue @ "\"" );
  1046. }
  1047. else
  1048. {
  1049. OptionsMenu.unappliedChanges.setValue("\"" @ %currentValue @ "\"", %prefIndex);
  1050. }
  1051. }
  1052. //Update the UI in case there's responsive logic
  1053. OptionsMenu.schedule(32, "refresh");
  1054. }
  1055. function OptionsMenu::onKeybindChanged(%this, %actionMap, %keybind)
  1056. {
  1057. %prefIndex = OptionsMenu.unappliedChanges.getIndexFromKey(%actionMap);
  1058. if(%prefIndex == -1)
  1059. OptionsMenu.unappliedChanges.add(%actionMap, %keybind);
  1060. else
  1061. OptionsMenu.unappliedChanges.setValue(%keybind, %prefIndex);
  1062. }
  1063. //
  1064. // Indicates what category the options item should be added into
  1065. //
  1066. function addOptionsMenuCategory(%categoryName, %selectCallback)
  1067. {
  1068. //Don't add duplicates!
  1069. %index = OptionsMenu.optionsCategories.getIndexFromKey(%categoryName);
  1070. if(%index == -1)
  1071. OptionsMenu.optionsCategories.add(%categoryName, %selectCallback);
  1072. }
  1073. function removeOptionsMenuCategory(%categoryName)
  1074. {
  1075. %index = OptionsMenu.optionsCategories.getIndexFromKey(%categoryName);
  1076. if(%index != -1)
  1077. OptionsMenu.optionsCategories.erase(%index);
  1078. }
  1079. function getOptionsCategoryIndexByName(%categoryName)
  1080. {
  1081. for(%i=0; %i < OptionsMenu.optionsCategories.count(); %i++)
  1082. {
  1083. if(OptionsMenu.optionsCategories.getKey(%i) $= %categoryName)
  1084. return %i;
  1085. }
  1086. return -1;
  1087. }
  1088. function addListOption(%label, %description, %targetPrefVar, %optionsList, %wrapOptions, %callback, %enabled)
  1089. {
  1090. if(%wrapOptions $= "")
  1091. %wrapOptions = false;
  1092. if(%enabled $= "")
  1093. %enabled = true;
  1094. OptionsMenuSettingsList.addOptionRow(%label, %targetPrefVar, %optionsList, %wrapOptions, %callback, %enabled, %description, %targetPrefVar);
  1095. }
  1096. function addSliderOption(%label, %description, %targetPrefVar, %defaultValue, %increment, %range, %callback, %enabled)
  1097. {
  1098. if(%enabled $= "")
  1099. %enabled = true;
  1100. OptionsMenuSettingsList.addSliderRow(%label, %targetPrefVar, %defaultValue, %increment, %range, %callback, %enabled, %description);
  1101. }
  1102. function addKeybindOption(%label, %description, %bitmapName, %callback, %enabled)
  1103. {
  1104. if(%enabled $= "")
  1105. %enabled = true;
  1106. OptionsMenuSettingsList.addSliderRow(%label, %bitmapName, %callback, %enabled, %description);
  1107. }
  1108. //
  1109. //
  1110. //
  1111. function addOptionGroup()
  1112. {
  1113. %group = new GuiTextCtrl() {
  1114. text = "Graphics";
  1115. position = "0 0";
  1116. extent = "500 30";
  1117. profile = "MenuHeaderText";
  1118. tooltipProfile = "GuiToolTipProfile";
  1119. };
  1120. return %group;
  1121. }
  1122. function optionsMenuButton::onHighlighted(%this, %highlighted)
  1123. {
  1124. %container = %this.getParent();
  1125. %container-->optionName.profile = %highlighted ? MenuSubHeaderTextHighlighted : MenuSubHeaderText;
  1126. %container-->optionDescription.profile = %highlighted ? GuiMLTextProfileHighlighted : GuiMLTextProfile;
  1127. %valuesContainer = %container-->valuesContainer;
  1128. %valuesContainer-->optionValue.profile = %highlighted ? GuiMenuTextProfileHighlighted : GuiMenuTextProfile;
  1129. }
  1130. function optionsMenuButton::onMouseDown(%this)
  1131. {
  1132. //check if we're clicking on the left or right of the value and adjust it accordingly
  1133. }
  1134. function addOptionEntry(%optionObj)
  1135. {
  1136. if(!isObject(%optionObj) || %optionObj.class !$= "OptionsSettings")
  1137. {
  1138. error("addOptionsEntry() - attempting to create a new options entry, but was provided an invalid options object");
  1139. return 0;
  1140. }
  1141. %qualityLevel = %optionObj.getObject(0);
  1142. %entry = new GuiContainer() {
  1143. position = "0 0";
  1144. extent = "500 40";
  1145. profile = GuiMenuDefaultProfile;
  1146. tooltipProfile = "GuiToolTipProfile";
  1147. horizSizing = "width";
  1148. vertSizing = "bottom";
  1149. class = "OptionsListEntry";
  1150. optionsObject = %optionObj;
  1151. currentOptionIndex = 0;
  1152. new GuiButtonCtrl() {
  1153. profile = GuiMenuButtonProfile;
  1154. position = "0 0";
  1155. extent = "500 40";
  1156. horizSizing = "width";
  1157. vertSizing = "height";
  1158. internalName = "button";
  1159. class = "optionsMenuButton";
  1160. };
  1161. new GuiTextCtrl() {
  1162. text = %optionObj.OptionName;
  1163. position = $optionsEntryPad SPC -1;
  1164. extent = "250 20";
  1165. profile = "MenuSubHeaderText";
  1166. tooltipProfile = "GuiToolTipProfile";
  1167. internalName = "optionName";
  1168. };
  1169. new GuiTextCtrl() {
  1170. text = %optionObj.Description;
  1171. position = $optionsEntryPad SPC 17;
  1172. extent = "250 18";
  1173. profile = "GuiMLTextProfile";
  1174. tooltipProfile = "GuiToolTipProfile";
  1175. internalName = "optionDescription";
  1176. };
  1177. new GuiContainer() {
  1178. position = "250 0";
  1179. extent = "250 40";
  1180. profile = GuiModelessDialogProfile;
  1181. tooltipProfile = "GuiToolTipProfile";
  1182. horizSizing = "left";
  1183. vertSizing = "height";
  1184. internalName = "valuesContainer";
  1185. new GuiButtonCtrl() {
  1186. position = "160 0";
  1187. extent = "20 40";
  1188. text = "<";
  1189. profile = GuiMenuButtonProfile;
  1190. };
  1191. new GuiTextCtrl() {
  1192. text = %qualityLevel.displayName;
  1193. position = "180 0";
  1194. extent = "50 40";
  1195. profile = "GuiMenuTextProfile";
  1196. tooltipProfile = "GuiToolTipProfile";
  1197. horizSizing = "right";
  1198. vertSizing = "center";
  1199. internalName = "optionValue";
  1200. };
  1201. new GuiButtonCtrl() {
  1202. position = "230 0";
  1203. extent = "20 40";
  1204. text = ">";
  1205. profile = GuiMenuButtonProfile;
  1206. };
  1207. };
  1208. };
  1209. return %entry;
  1210. }