optionsDlg.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. /// Returns true if the current quality settings equal
  23. /// this graphics quality level.
  24. function GraphicsQualityLevel::isCurrent( %this )
  25. {
  26. // Test each pref to see if the current value
  27. // equals our stored value.
  28. for ( %i=0; %i < %this.count(); %i++ )
  29. {
  30. %pref = %this.getKey( %i );
  31. %value = %this.getValue( %i );
  32. if ( getVariable( %pref ) !$= %value )
  33. return false;
  34. }
  35. return true;
  36. }
  37. /// Applies the graphics quality settings and calls
  38. /// 'onApply' on itself or its parent group if its
  39. /// been overloaded.
  40. function GraphicsQualityLevel::apply( %this )
  41. {
  42. for ( %i=0; %i < %this.count(); %i++ )
  43. {
  44. %pref = %this.getKey( %i );
  45. %value = %this.getValue( %i );
  46. setVariable( %pref, %value );
  47. }
  48. // If we have an overloaded onApply method then
  49. // call it now to finalize the changes.
  50. if ( %this.isMethod( "onApply" ) )
  51. %this.onApply();
  52. else
  53. {
  54. %group = %this.getGroup();
  55. if ( isObject( %group ) && %group.isMethod( "onApply" ) )
  56. %group.onApply( %this );
  57. }
  58. }
  59. function GraphicsQualityPopup::init( %this, %qualityGroup )
  60. {
  61. assert( isObject( %this ) );
  62. assert( isObject( %qualityGroup ) );
  63. // Clear the existing content first.
  64. %this.clear();
  65. // Fill it.
  66. %select = -1;
  67. for ( %i=0; %i < %qualityGroup.getCount(); %i++ )
  68. {
  69. %level = %qualityGroup.getObject( %i );
  70. if ( %level.isCurrent() )
  71. %select = %i;
  72. %this.add( %level.getInternalName(), %i );
  73. }
  74. // Setup a default selection.
  75. if ( %select == -1 )
  76. %this.setText( "Custom" );
  77. else
  78. %this.setSelected( %select );
  79. }
  80. function GraphicsQualityPopup::apply( %this, %qualityGroup, %testNeedApply )
  81. {
  82. assert( isObject( %this ) );
  83. assert( isObject( %qualityGroup ) );
  84. %quality = %this.getText();
  85. %index = %this.findText( %quality );
  86. if ( %index == -1 )
  87. return false;
  88. %level = %qualityGroup.getObject( %index );
  89. if ( isObject( %level ) && !%level.isCurrent() )
  90. {
  91. if ( %testNeedApply )
  92. return true;
  93. %level.apply();
  94. }
  95. return false;
  96. }
  97. function OptionsDlg::setPane(%this, %pane)
  98. {
  99. %this-->OptAudioPane.setVisible(false);
  100. %this-->OptGraphicsPane.setVisible(false);
  101. %this-->OptNetworkPane.setVisible(false);
  102. %this-->OptControlsPane.setVisible(false);
  103. %this.findObjectByInternalName( "Opt" @ %pane @ "Pane", true ).setVisible(true);
  104. %this.fillRemapList();
  105. // Update the state of the apply button.
  106. %this._updateApplyState();
  107. }
  108. function OptionsDlg::onWake(%this)
  109. {
  110. if ( isFunction("getWebDeployment") && getWebDeployment() )
  111. {
  112. // Cannot enable full screen under web deployment
  113. %this-->OptGraphicsFullscreenToggle.setStateOn( false );
  114. %this-->OptGraphicsFullscreenToggle.setVisible( false );
  115. }
  116. else
  117. {
  118. %this-->OptGraphicsFullscreenToggle.setStateOn( Canvas.isFullScreen() );
  119. }
  120. %this-->OptGraphicsVSyncToggle.setStateOn( !$pref::Video::disableVerticalSync );
  121. OptionsDlg.initResMenu();
  122. %resSelId = OptionsDlg-->OptGraphicsResolutionMenu.findText( _makePrettyResString( $pref::Video::mode ) );
  123. if( %resSelId != -1 )
  124. OptionsDlg-->OptGraphicsResolutionMenu.setSelected( %resSelId );
  125. OptGraphicsDriverMenu.clear();
  126. %buffer = getDisplayDeviceList();
  127. %count = getFieldCount( %buffer );
  128. for(%i = 0; %i < %count; %i++)
  129. OptGraphicsDriverMenu.add(getField(%buffer, %i), %i);
  130. %selId = OptGraphicsDriverMenu.findText( getDisplayDeviceInformation() );
  131. if ( %selId == -1 )
  132. OptGraphicsDriverMenu.setFirstSelected();
  133. else
  134. OptGraphicsDriverMenu.setSelected( %selId );
  135. // Setup the graphics quality dropdown menus.
  136. %this-->OptMeshQualityPopup.init( MeshQualityGroup );
  137. %this-->OptTextureQualityPopup.init( TextureQualityGroup );
  138. %this-->OptLightingQualityPopup.init( LightingQualityGroup );
  139. %this-->OptShaderQualityPopup.init( ShaderQualityGroup );
  140. // Setup the anisotropic filtering menu.
  141. %ansioCtrl = %this-->OptAnisotropicPopup;
  142. %ansioCtrl.clear();
  143. %ansioCtrl.add( "Off", 0 );
  144. %ansioCtrl.add( "4X", 4 );
  145. %ansioCtrl.add( "8X", 8 );
  146. %ansioCtrl.add( "16X", 16 );
  147. %ansioCtrl.setSelected( $pref::Video::defaultAnisotropy, false );
  148. // set up the Refresh Rate menu.
  149. %refreshMenu = %this-->OptRefreshSelectMenu;
  150. %refreshMenu.clear();
  151. // %refreshMenu.add("Auto", 60);
  152. %refreshMenu.add("60", 60);
  153. %refreshMenu.add("75", 75);
  154. %refreshMenu.setSelected( getWord( $pref::Video::mode, $WORD::REFRESH ) );
  155. // Audio
  156. //OptAudioHardwareToggle.setStateOn($pref::SFX::useHardware);
  157. //OptAudioHardwareToggle.setActive( true );
  158. %this-->OptAudioVolumeMaster.setValue( $pref::SFX::masterVolume );
  159. %this-->OptAudioVolumeShell.setValue( $pref::SFX::channelVolume[ $GuiAudioType] );
  160. %this-->OptAudioVolumeSim.setValue( $pref::SFX::channelVolume[ $SimAudioType ] );
  161. %this-->OptAudioVolumeMusic.setValue( $pref::SFX::channelVolume[ $MusicAudioType ] );
  162. OptAudioProviderList.clear();
  163. %buffer = sfxGetAvailableDevices();
  164. %count = getRecordCount( %buffer );
  165. for(%i = 0; %i < %count; %i++)
  166. {
  167. %record = getRecord(%buffer, %i);
  168. %provider = getField(%record, 0);
  169. if ( OptAudioProviderList.findText( %provider ) == -1 )
  170. OptAudioProviderList.add( %provider, %i );
  171. }
  172. OptAudioProviderList.sort();
  173. %selId = OptAudioProviderList.findText($pref::SFX::provider);
  174. if ( %selId == -1 )
  175. OptAudioProviderList.setFirstSelected();
  176. else
  177. OptAudioProviderList.setSelected( %selId );
  178. // Populate the Anti-aliasing popup.
  179. %aaMenu = %this-->OptAAQualityPopup;
  180. %aaMenu.clear();
  181. %aaMenu.Add( "Off", 0 );
  182. %aaMenu.Add( "1x", 1 );
  183. %aaMenu.Add( "2x", 2 );
  184. %aaMenu.Add( "4x", 4 );
  185. %aaMenu.setSelected( getWord( $pref::Video::mode, $WORD::AA ) );
  186. OptMouseSensitivity.value = $pref::Input::LinkMouseSensitivity;
  187. // Set the graphics pane to start.
  188. %this-->OptGraphicsButton.performClick();
  189. }
  190. function OptionsDlg::onSleep(%this)
  191. {
  192. // write out the control config into the rw/config.cs file
  193. moveMap.save( "scripts/client/config.cs" );
  194. }
  195. function OptGraphicsDriverMenu::onSelect( %this, %id, %text )
  196. {
  197. // Attempt to keep the same resolution settings:
  198. %resMenu = OptionsDlg-->OptGraphicsResolutionMenu;
  199. %currRes = %resMenu.getText();
  200. // If its empty the use the current.
  201. if ( %currRes $= "" )
  202. %currRes = _makePrettyResString( Canvas.getVideoMode() );
  203. // Fill the resolution list.
  204. optionsDlg.initResMenu();
  205. // Try to select the previous settings:
  206. %selId = %resMenu.findText( %currRes );
  207. if ( %selId == -1 )
  208. %selId = 0;
  209. %resMenu.setSelected( %selId );
  210. OptionsDlg._updateApplyState();
  211. }
  212. function _makePrettyResString( %resString )
  213. {
  214. %width = getWord( %resString, $WORD::RES_X );
  215. %height = getWord( %resString, $WORD::RES_Y );
  216. %aspect = %width / %height;
  217. %aspect = mRound( %aspect * 100 ) * 0.01;
  218. switch$( %aspect )
  219. {
  220. case "1.33":
  221. %aspect = "4:3";
  222. case "1.78":
  223. %aspect = "16:9";
  224. default:
  225. %aspect = "";
  226. }
  227. %outRes = %width @ " x " @ %height;
  228. if ( %aspect !$= "" )
  229. %outRes = %outRes @ " (" @ %aspect @ ")";
  230. return %outRes;
  231. }
  232. function OptionsDlg::initResMenu( %this )
  233. {
  234. // Clear out previous values
  235. %resMenu = %this-->OptGraphicsResolutionMenu;
  236. %resMenu.clear();
  237. // If we are in a browser then we can't change our resolution through
  238. // the options dialog
  239. if (getWebDeployment())
  240. {
  241. %count = 0;
  242. %currRes = getWords(Canvas.getVideoMode(), $WORD::RES_X, $WORD::RES_Y);
  243. %resMenu.add(%currRes, %count);
  244. %count++;
  245. return;
  246. }
  247. // Loop through all and add all valid resolutions
  248. %count = 0;
  249. %resCount = Canvas.getModeCount();
  250. for (%i = 0; %i < %resCount; %i++)
  251. {
  252. %testResString = Canvas.getMode( %i );
  253. %testRes = _makePrettyResString( %testResString );
  254. // Only add to list if it isn't there already.
  255. if (%resMenu.findText(%testRes) == -1)
  256. {
  257. %resMenu.add(%testRes, %i);
  258. %count++;
  259. }
  260. }
  261. %resMenu.sort();
  262. }
  263. function OptionsDlg::applyGraphics( %this, %testNeedApply )
  264. {
  265. %newAdapter = OptGraphicsDriverMenu.getText();
  266. %numAdapters = GFXInit::getAdapterCount();
  267. %newDevice = $pref::Video::displayDevice;
  268. for( %i = 0; %i < %numAdapters; %i ++ )
  269. if( GFXInit::getAdapterName( %i ) $= %newAdapter )
  270. {
  271. %newDevice = GFXInit::getAdapterType( %i );
  272. break;
  273. }
  274. // Change the device.
  275. if ( %newDevice !$= $pref::Video::displayDevice )
  276. {
  277. if ( %testNeedApply )
  278. return true;
  279. $pref::Video::displayDevice = %newDevice;
  280. if( %newAdapter !$= getDisplayDeviceInformation() )
  281. MessageBoxOK( "Change requires restart", "Please restart the game for a display device change to take effect." );
  282. }
  283. // Gather the new video mode.
  284. if ( isFunction("getWebDeployment") && getWebDeployment() )
  285. {
  286. // Under web deployment, we use the custom resolution rather than a Canvas
  287. // defined one.
  288. %newRes = %this-->OptGraphicsResolutionMenu.getText();
  289. }
  290. else
  291. {
  292. %newRes = getWords( Canvas.getMode( %this-->OptGraphicsResolutionMenu.getSelected() ), $WORD::RES_X, $WORD::RES_Y );
  293. }
  294. %newBpp = 32; // ... its not 1997 anymore.
  295. %newFullScreen = %this-->OptGraphicsFullscreenToggle.getValue() ? "true" : "false";
  296. %newRefresh = %this-->OptRefreshSelectMenu.getSelected();
  297. %newVsync = !%this-->OptGraphicsVSyncToggle.getValue();
  298. %newFSAA = %this-->OptAAQualityPopup.getSelected();
  299. // Under web deployment we can't be full screen.
  300. if ( isFunction("getWebDeployment") && getWebDeployment() )
  301. {
  302. %newFullScreen = false;
  303. }
  304. else if ( %newFullScreen $= "false" )
  305. {
  306. // If we're in windowed mode switch the fullscreen check
  307. // if the resolution is bigger than the desktop.
  308. %deskRes = getDesktopResolution();
  309. %deskResX = getWord(%deskRes, $WORD::RES_X);
  310. %deskResY = getWord(%deskRes, $WORD::RES_Y);
  311. if ( getWord( %newRes, $WORD::RES_X ) > %deskResX ||
  312. getWord( %newRes, $WORD::RES_Y ) > %deskResY )
  313. {
  314. %newFullScreen = "true";
  315. %this-->OptGraphicsFullscreenToggle.setStateOn( true );
  316. }
  317. }
  318. // Build the final mode string.
  319. %newMode = %newRes SPC %newFullScreen SPC %newBpp SPC %newRefresh SPC %newFSAA;
  320. // Change the video mode.
  321. if ( %newMode !$= $pref::Video::mode ||
  322. %newVsync != $pref::Video::disableVerticalSync )
  323. {
  324. if ( %testNeedApply )
  325. return true;
  326. $pref::Video::mode = %newMode;
  327. $pref::Video::disableVerticalSync = %newVsync;
  328. configureCanvas();
  329. }
  330. // Test and apply the graphics settings.
  331. if ( %this-->OptMeshQualityPopup.apply( MeshQualityGroup, %testNeedApply ) ) return true;
  332. if ( %this-->OptTextureQualityPopup.apply( TextureQualityGroup, %testNeedApply ) ) return true;
  333. if ( %this-->OptLightingQualityPopup.apply( LightingQualityGroup, %testNeedApply ) ) return true;
  334. if ( %this-->OptShaderQualityPopup.apply( ShaderQualityGroup, %testNeedApply ) ) return true;
  335. // Check the anisotropic filtering.
  336. %level = %this-->OptAnisotropicPopup.getSelected();
  337. if ( %level != $pref::Video::defaultAnisotropy )
  338. {
  339. if ( %testNeedApply )
  340. return true;
  341. $pref::Video::defaultAnisotropy = %level;
  342. }
  343. // If we're applying the state then recheck the
  344. // state to update the apply button.
  345. if ( !%testNeedApply )
  346. %this._updateApplyState();
  347. return false;
  348. }
  349. function OptionsDlg::_updateApplyState( %this )
  350. {
  351. %applyCtrl = %this-->Apply;
  352. %graphicsPane = %this-->OptGraphicsPane;
  353. assert( isObject( %applyCtrl ) );
  354. assert( isObject( %graphicsPane ) );
  355. %applyCtrl.active = %graphicsPane.isVisible() && %this.applyGraphics( true );
  356. }
  357. function OptionsDlg::_autoDetectQuality( %this )
  358. {
  359. %msg = GraphicsQualityAutodetect();
  360. %this.onWake();
  361. if ( %msg !$= "" )
  362. {
  363. MessageBoxOK( "Notice", %msg );
  364. }
  365. }
  366. $RemapCount = 0;
  367. $RemapName[$RemapCount] = "Forward";
  368. $RemapCmd[$RemapCount] = "moveforward";
  369. $RemapCount++;
  370. $RemapName[$RemapCount] = "Backward";
  371. $RemapCmd[$RemapCount] = "movebackward";
  372. $RemapCount++;
  373. $RemapName[$RemapCount] = "Strafe Left";
  374. $RemapCmd[$RemapCount] = "moveleft";
  375. $RemapCount++;
  376. $RemapName[$RemapCount] = "Strafe Right";
  377. $RemapCmd[$RemapCount] = "moveright";
  378. $RemapCount++;
  379. $RemapName[$RemapCount] = "Turn Left";
  380. $RemapCmd[$RemapCount] = "turnLeft";
  381. $RemapCount++;
  382. $RemapName[$RemapCount] = "Turn Right";
  383. $RemapCmd[$RemapCount] = "turnRight";
  384. $RemapCount++;
  385. $RemapName[$RemapCount] = "Look Up";
  386. $RemapCmd[$RemapCount] = "panUp";
  387. $RemapCount++;
  388. $RemapName[$RemapCount] = "Look Down";
  389. $RemapCmd[$RemapCount] = "panDown";
  390. $RemapCount++;
  391. $RemapName[$RemapCount] = "Jump";
  392. $RemapCmd[$RemapCount] = "jump";
  393. $RemapCount++;
  394. $RemapName[$RemapCount] = "Fire Weapon";
  395. $RemapCmd[$RemapCount] = "mouseFire";
  396. $RemapCount++;
  397. $RemapName[$RemapCount] = "Adjust Zoom";
  398. $RemapCmd[$RemapCount] = "setZoomFov";
  399. $RemapCount++;
  400. $RemapName[$RemapCount] = "Toggle Zoom";
  401. $RemapCmd[$RemapCount] = "toggleZoom";
  402. $RemapCount++;
  403. $RemapName[$RemapCount] = "Free Look";
  404. $RemapCmd[$RemapCount] = "toggleFreeLook";
  405. $RemapCount++;
  406. $RemapName[$RemapCount] = "Switch 1st/3rd";
  407. $RemapCmd[$RemapCount] = "toggleFirstPerson";
  408. $RemapCount++;
  409. $RemapName[$RemapCount] = "Chat to Everyone";
  410. $RemapCmd[$RemapCount] = "toggleMessageHud";
  411. $RemapCount++;
  412. $RemapName[$RemapCount] = "Message Hud PageUp";
  413. $RemapCmd[$RemapCount] = "pageMessageHudUp";
  414. $RemapCount++;
  415. $RemapName[$RemapCount] = "Message Hud PageDown";
  416. $RemapCmd[$RemapCount] = "pageMessageHudDown";
  417. $RemapCount++;
  418. $RemapName[$RemapCount] = "Resize Message Hud";
  419. $RemapCmd[$RemapCount] = "resizeMessageHud";
  420. $RemapCount++;
  421. $RemapName[$RemapCount] = "Show Scores";
  422. $RemapCmd[$RemapCount] = "showPlayerList";
  423. $RemapCount++;
  424. $RemapName[$RemapCount] = "Animation - Wave";
  425. $RemapCmd[$RemapCount] = "celebrationWave";
  426. $RemapCount++;
  427. $RemapName[$RemapCount] = "Animation - Salute";
  428. $RemapCmd[$RemapCount] = "celebrationSalute";
  429. $RemapCount++;
  430. $RemapName[$RemapCount] = "Suicide";
  431. $RemapCmd[$RemapCount] = "suicide";
  432. $RemapCount++;
  433. $RemapName[$RemapCount] = "Toggle Camera";
  434. $RemapCmd[$RemapCount] = "toggleCamera";
  435. $RemapCount++;
  436. $RemapName[$RemapCount] = "Drop Camera at Player";
  437. $RemapCmd[$RemapCount] = "dropCameraAtPlayer";
  438. $RemapCount++;
  439. $RemapName[$RemapCount] = "Drop Player at Camera";
  440. $RemapCmd[$RemapCount] = "dropPlayerAtCamera";
  441. $RemapCount++;
  442. $RemapName[$RemapCount] = "Bring up Options Dialog";
  443. $RemapCmd[$RemapCount] = "bringUpOptions";
  444. $RemapCount++;
  445. function restoreDefaultMappings()
  446. {
  447. moveMap.delete();
  448. exec( "scripts/client/default.bind.cs" );
  449. optionsDlg.fillRemapList();
  450. }
  451. function getMapDisplayName( %device, %action )
  452. {
  453. if ( %device $= "keyboard" )
  454. return( %action );
  455. else if ( strstr( %device, "mouse" ) != -1 )
  456. {
  457. // Substitute "mouse" for "button" in the action string:
  458. %pos = strstr( %action, "button" );
  459. if ( %pos != -1 )
  460. {
  461. %mods = getSubStr( %action, 0, %pos );
  462. %object = getSubStr( %action, %pos, 1000 );
  463. %instance = getSubStr( %object, strlen( "button" ), 1000 );
  464. return( %mods @ "mouse" @ ( %instance + 1 ) );
  465. }
  466. else
  467. error( "Mouse input object other than button passed to getDisplayMapName!" );
  468. }
  469. else if ( strstr( %device, "joystick" ) != -1 )
  470. {
  471. // Substitute "joystick" for "button" in the action string:
  472. %pos = strstr( %action, "button" );
  473. if ( %pos != -1 )
  474. {
  475. %mods = getSubStr( %action, 0, %pos );
  476. %object = getSubStr( %action, %pos, 1000 );
  477. %instance = getSubStr( %object, strlen( "button" ), 1000 );
  478. return( %mods @ "joystick" @ ( %instance + 1 ) );
  479. }
  480. else
  481. {
  482. %pos = strstr( %action, "pov" );
  483. if ( %pos != -1 )
  484. {
  485. %wordCount = getWordCount( %action );
  486. %mods = %wordCount > 1 ? getWords( %action, 0, %wordCount - 2 ) @ " " : "";
  487. %object = getWord( %action, %wordCount - 1 );
  488. switch$ ( %object )
  489. {
  490. case "upov": %object = "POV1 up";
  491. case "dpov": %object = "POV1 down";
  492. case "lpov": %object = "POV1 left";
  493. case "rpov": %object = "POV1 right";
  494. case "upov2": %object = "POV2 up";
  495. case "dpov2": %object = "POV2 down";
  496. case "lpov2": %object = "POV2 left";
  497. case "rpov2": %object = "POV2 right";
  498. default: %object = "??";
  499. }
  500. return( %mods @ %object );
  501. }
  502. else
  503. error( "Unsupported Joystick input object passed to getDisplayMapName!" );
  504. }
  505. }
  506. return( "??" );
  507. }
  508. function buildFullMapString( %index )
  509. {
  510. %name = $RemapName[%index];
  511. %cmd = $RemapCmd[%index];
  512. %temp = moveMap.getBinding( %cmd );
  513. if ( %temp $= "" )
  514. return %name TAB "";
  515. %mapString = "";
  516. %count = getFieldCount( %temp );
  517. for ( %i = 0; %i < %count; %i += 2 )
  518. {
  519. if ( %mapString !$= "" )
  520. %mapString = %mapString @ ", ";
  521. %device = getField( %temp, %i + 0 );
  522. %object = getField( %temp, %i + 1 );
  523. %mapString = %mapString @ getMapDisplayName( %device, %object );
  524. }
  525. return %name TAB %mapString;
  526. }
  527. function OptionsDlg::fillRemapList( %this )
  528. {
  529. %remapList = %this-->OptRemapList;
  530. %remapList.clear();
  531. for ( %i = 0; %i < $RemapCount; %i++ )
  532. %remapList.addRow( %i, buildFullMapString( %i ) );
  533. }
  534. function OptionsDlg::doRemap( %this )
  535. {
  536. %remapList = %this-->OptRemapList;
  537. %selId = %remapList.getSelectedId();
  538. %name = $RemapName[%selId];
  539. RemapDlg-->OptRemapText.setValue( "Re-bind \"" @ %name @ "\" to..." );
  540. OptRemapInputCtrl.index = %selId;
  541. Canvas.pushDialog( RemapDlg );
  542. }
  543. function redoMapping( %device, %action, %cmd, %oldIndex, %newIndex )
  544. {
  545. //%actionMap.bind( %device, %action, $RemapCmd[%newIndex] );
  546. moveMap.bind( %device, %action, %cmd );
  547. %remapList = %this-->OptRemapList;
  548. %remapList.setRowById( %oldIndex, buildFullMapString( %oldIndex ) );
  549. %remapList.setRowById( %newIndex, buildFullMapString( %newIndex ) );
  550. }
  551. function findRemapCmdIndex( %command )
  552. {
  553. for ( %i = 0; %i < $RemapCount; %i++ )
  554. {
  555. if ( %command $= $RemapCmd[%i] )
  556. return( %i );
  557. }
  558. return( -1 );
  559. }
  560. /// This unbinds actions beyond %count associated to the
  561. /// particular moveMap %commmand.
  562. function unbindExtraActions( %command, %count )
  563. {
  564. %temp = moveMap.getBinding( %command );
  565. if ( %temp $= "" )
  566. return;
  567. %count = getFieldCount( %temp ) - ( %count * 2 );
  568. for ( %i = 0; %i < %count; %i += 2 )
  569. {
  570. %device = getField( %temp, %i + 0 );
  571. %action = getField( %temp, %i + 1 );
  572. moveMap.unbind( %device, %action );
  573. }
  574. }
  575. function OptRemapInputCtrl::onInputEvent( %this, %device, %action )
  576. {
  577. //error( "** onInputEvent called - device = " @ %device @ ", action = " @ %action @ " **" );
  578. Canvas.popDialog( RemapDlg );
  579. // Test for the reserved keystrokes:
  580. if ( %device $= "keyboard" )
  581. {
  582. // Cancel...
  583. if ( %action $= "escape" )
  584. {
  585. // Do nothing...
  586. return;
  587. }
  588. }
  589. %cmd = $RemapCmd[%this.index];
  590. %name = $RemapName[%this.index];
  591. // Grab the friendly display name for this action
  592. // which we'll use when prompting the user below.
  593. %mapName = getMapDisplayName( %device, %action );
  594. // Get the current command this action is mapped to.
  595. %prevMap = moveMap.getCommand( %device, %action );
  596. // If nothing was mapped to the previous command
  597. // mapping then it's easy... just bind it.
  598. if ( %prevMap $= "" )
  599. {
  600. unbindExtraActions( %cmd, 1 );
  601. moveMap.bind( %device, %action, %cmd );
  602. optionsDlg-->OptRemapList.setRowById( %this.index, buildFullMapString( %this.index ) );
  603. return;
  604. }
  605. // If the previous command is the same as the
  606. // current then they hit the same input as what
  607. // was already assigned.
  608. if ( %prevMap $= %cmd )
  609. {
  610. unbindExtraActions( %cmd, 0 );
  611. moveMap.bind( %device, %action, %cmd );
  612. optionsDlg-->OptRemapList.setRowById( %this.index, buildFullMapString( %this.index ) );
  613. return;
  614. }
  615. // Look for the index of the previous mapping.
  616. %prevMapIndex = findRemapCmdIndex( %prevMap );
  617. // If we get a negative index then the previous
  618. // mapping was to an item that isn't included in
  619. // the mapping list... so we cannot unmap it.
  620. if ( %prevMapIndex == -1 )
  621. {
  622. MessageBoxOK( "Remap Failed", "\"" @ %mapName @ "\" is already bound to a non-remappable command!" );
  623. return;
  624. }
  625. // Setup the forced remapping callback command.
  626. %callback = "redoMapping(" @ %device @ ", \"" @ %action @ "\", \"" @
  627. %cmd @ "\", " @ %prevMapIndex @ ", " @ %this.index @ ");";
  628. // Warn that we're about to remove the old mapping and
  629. // replace it with another.
  630. %prevCmdName = $RemapName[%prevMapIndex];
  631. MessageBoxYesNo( "Warning",
  632. "\"" @ %mapName @ "\" is already bound to \""
  633. @ %prevCmdName @ "\"!\nDo you wish to replace this mapping?",
  634. %callback, "" );
  635. }
  636. $AudioTestHandle = 0;
  637. // Description to use for playing the volume test sound. This isn't
  638. // played with the description of the channel that has its volume changed
  639. // because we know nothing about the playback state of the channel. If it
  640. // is paused or stopped, the test sound would not play then.
  641. $AudioTestDescription = new SFXDescription()
  642. {
  643. sourceGroup = AudioChannelMaster;
  644. };
  645. function OptAudioUpdateMasterVolume( %volume )
  646. {
  647. if( %volume == $pref::SFX::masterVolume )
  648. return;
  649. sfxSetMasterVolume( %volume );
  650. $pref::SFX::masterVolume = %volume;
  651. if( !isObject( $AudioTestHandle ) )
  652. $AudioTestHandle = sfxPlayOnce( AudioChannel, "art/sound/ui/volumeTest.wav" );
  653. }
  654. function OptAudioUpdateChannelVolume( %description, %volume )
  655. {
  656. %channel = sfxGroupToOldChannel( %description.sourceGroup );
  657. if( %volume == $pref::SFX::channelVolume[ %channel ] )
  658. return;
  659. sfxSetChannelVolume( %channel, %volume );
  660. $pref::SFX::channelVolume[ %channel ] = %volume;
  661. if( !isObject( $AudioTestHandle ) )
  662. {
  663. $AudioTestDescription.volume = %volume;
  664. $AudioTestHandle = sfxPlayOnce( $AudioTestDescription, "art/sound/ui/volumeTest.wav" );
  665. }
  666. }
  667. function OptAudioProviderList::onSelect( %this, %id, %text )
  668. {
  669. // Skip empty provider selections.
  670. if ( %text $= "" )
  671. return;
  672. $pref::SFX::provider = %text;
  673. OptAudioDeviceList.clear();
  674. %buffer = sfxGetAvailableDevices();
  675. %count = getRecordCount( %buffer );
  676. for(%i = 0; %i < %count; %i++)
  677. {
  678. %record = getRecord(%buffer, %i);
  679. %provider = getField(%record, 0);
  680. %device = getField(%record, 1);
  681. if (%provider !$= %text)
  682. continue;
  683. if ( OptAudioDeviceList.findText( %device ) == -1 )
  684. OptAudioDeviceList.add( %device, %i );
  685. }
  686. // Find the previous selected device.
  687. %selId = OptAudioDeviceList.findText($pref::SFX::device);
  688. if ( %selId == -1 )
  689. OptAudioDeviceList.setFirstSelected();
  690. else
  691. OptAudioDeviceList.setSelected( %selId );
  692. }
  693. function OptAudioDeviceList::onSelect( %this, %id, %text )
  694. {
  695. // Skip empty selections.
  696. if ( %text $= "" )
  697. return;
  698. $pref::SFX::device = %text;
  699. if ( !sfxCreateDevice( $pref::SFX::provider,
  700. $pref::SFX::device,
  701. $pref::SFX::useHardware,
  702. -1 ) )
  703. error( "Unable to create SFX device: " @ $pref::SFX::provider
  704. SPC $pref::SFX::device
  705. SPC $pref::SFX::useHardware );
  706. }
  707. function OptMouseSetSensitivity(%value)
  708. {
  709. $pref::Input::LinkMouseSensitivity = %value;
  710. }
  711. /*
  712. function OptAudioHardwareToggle::onClick(%this)
  713. {
  714. if (!sfxCreateDevice($pref::SFX::provider, $pref::SFX::device, $pref::SFX::useHardware, -1))
  715. error("Unable to create SFX device: " @ $pref::SFX::provider SPC $pref::SFX::device SPC $pref::SFX::useHardware);
  716. }
  717. */