Options.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. //-----------------------------------------------------------------------------
  2. // Options.cs
  3. //
  4. // Microsoft XNA Community Game Platform
  5. // Copyright (C) Microsoft Corporation. All rights reserved.
  6. //-----------------------------------------------------------------------------
  7. using Microsoft.Xna.Framework;
  8. using Microsoft.Xna.Framework.Graphics;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Globalization;
  12. using System.Text;
  13. using RacingGame.GameLogic;
  14. using RacingGame.Graphics;
  15. using RacingGame.Helpers;
  16. using RacingGame.Properties;
  17. using RacingGame.Sounds;
  18. namespace RacingGame.GameScreens
  19. {
  20. /// <summary>
  21. /// Options
  22. /// </summary>
  23. /// <returns>IGame screen</returns>
  24. class Options : IGameScreen
  25. {
  26. readonly Rectangle
  27. Line4ArrowGfxRect = new Rectangle(154, 284, 62, 39),
  28. Line5ArrowGfxRect = new Rectangle(160, 354, 62, 39),
  29. Line6ArrowGfxRect = new Rectangle(72, 437, 62, 39),
  30. Resolution640x480GfxRect = new Rectangle(339, 112, 98, 32),
  31. Resolution800x600GfxRect = new Rectangle(454, 112, 98, 32),
  32. Resolution1024x768GfxRect = new Rectangle(575, 112, 108, 32),
  33. Resolution1280x1024GfxRect = new Rectangle(704, 112, 116, 32),
  34. ResolutionAutoGfxRect = new Rectangle(838, 112, 69, 32),
  35. FullscreenGfxRect = new Rectangle(339, 182, 105, 36),
  36. PostScreenEffectsGfxRect = new Rectangle(339, 226, 206, 36),
  37. ShadowsGfxRect = new Rectangle(616, 226, 90, 36),
  38. HighDetailGfxRect = new Rectangle(784, 226, 120, 36),
  39. SoundGfxRect = new Rectangle(384, 281, 448, 39),
  40. MusicGfxRect = new Rectangle(384, 354, 448, 39),
  41. SensitivityGfxRect = new Rectangle(384, 428, 448, 39);
  42. /// <summary>
  43. /// Current player name, copied from the settings file.
  44. /// Can be changed in this screen and will be saved to the settings file.
  45. /// Just a variable here to make it easier to change the name and
  46. /// because of performance (reading Settings every frame is not good).
  47. /// </summary>
  48. string currentPlayerName = GameSettings.Default.PlayerName;
  49. int currentOptionsNumber = 0;
  50. int currentResolution = 4;
  51. bool fullscreen = true;
  52. bool usePostScreenShaders = true;
  53. bool useShadowMapping = true;
  54. bool useHighDetail = true;
  55. float currentMusicVolume = 1.0f;
  56. float currentSoundVolume = 1.0f;
  57. float currentSensitivity = 1.0f;
  58. /// <summary>
  59. /// Create options
  60. /// </summary>
  61. public Options()
  62. {
  63. // Current resolution:
  64. // 0=640x480, 1=800x600, 2=1024x768, 3=1280x1024, 4=auto (default)
  65. if (BaseGame.Width == 640 && BaseGame.Height == 480)
  66. currentResolution = 0;
  67. if (BaseGame.Width == 800 && BaseGame.Height == 600)
  68. currentResolution = 1;
  69. if (BaseGame.Width == 1024 && BaseGame.Height == 768)
  70. currentResolution = 2;
  71. if (BaseGame.Width == 1280 && BaseGame.Height == 1024)
  72. currentResolution = 3;
  73. // Get graphics detail settings
  74. fullscreen = BaseGame.Fullscreen;
  75. usePostScreenShaders = BaseGame.UsePostScreenShaders;
  76. useShadowMapping = BaseGame.AllowShadowMapping;
  77. useHighDetail = BaseGame.HighDetail;
  78. // Get music and sound volume
  79. currentMusicVolume = GameSettings.Default.MusicVolume;
  80. currentSoundVolume = GameSettings.Default.SoundVolume;
  81. // Get sensitivity
  82. currentSensitivity = GameSettings.Default.ControllerSensitivity;
  83. }
  84. /// <summary>
  85. /// Unimplemented
  86. /// </summary>
  87. /// <param name="gameTime"></param>
  88. public void Update(GameTime gameTime)
  89. {
  90. }
  91. /// <summary>
  92. /// Render game screen. Called each frame.
  93. /// </summary>
  94. public bool Render()
  95. {
  96. // This starts both menu and in game post screen shader!
  97. if(BaseGame.UsePostScreenShaders)
  98. BaseGame.UI.PostScreenMenuShader.Start();
  99. // Render background and black bar
  100. BaseGame.UI.RenderMenuBackground();
  101. // Options header
  102. int posX = 10;
  103. int posY = 18;
  104. // UWP COMMENT OUT
  105. //if (Environment.OSVersion.Platform != PlatformID.Win32NT)
  106. //{
  107. // posX += 36;
  108. // posY += 26;
  109. //}
  110. BaseGame.UI.Headers.RenderOnScreenRelative1600(
  111. posX, posY, UIRenderer.HeaderOptionsGfxRect);
  112. // Options background
  113. BaseGame.UI.OptionsScreen.RenderOnScreenRelative4To3(
  114. 0, 125, BaseGame.UI.OptionsScreen.GfxRectangle);
  115. // Edit player name
  116. int xPos = BaseGame.XToRes(352);
  117. int yPos = BaseGame.YToRes768(125 + 65 - 20);
  118. TextureFont.WriteText(xPos, yPos,
  119. currentPlayerName +
  120. // Add blinking |
  121. ((int)(BaseGame.TotalTime / 0.35f) % 2 == 0 ? "|" : ""));
  122. Input.HandleKeyboardInput(ref currentPlayerName);
  123. #if !XBOX360
  124. // Select resolution
  125. // Use inverted color for selection (see below for sprite blend mode)
  126. Color selColor = new Color(255, 156, 0, 160);
  127. Rectangle res0Rect = BaseGame.CalcRectangleKeep4To3(
  128. Resolution640x480GfxRect);
  129. res0Rect.Y += BaseGame.YToRes768(125);
  130. bool inRes0Rect = Input.MouseInBox(res0Rect);
  131. if (currentResolution == 0)
  132. BaseGame.UI.OptionsScreen.RenderOnScreen(
  133. res0Rect, Resolution640x480GfxRect,
  134. selColor, BlendState.AlphaBlend);
  135. if (inRes0Rect && Input.MouseLeftButtonJustPressed)
  136. {
  137. Sound.Play(Sound.Sounds.ButtonClick);
  138. currentResolution = 0;
  139. }
  140. Rectangle res1Rect = BaseGame.CalcRectangleKeep4To3(
  141. Resolution800x600GfxRect);
  142. res1Rect.Y += BaseGame.YToRes768(125);
  143. bool inRes1Rect = Input.MouseInBox(res1Rect);
  144. if (currentResolution == 1)
  145. BaseGame.UI.OptionsScreen.RenderOnScreen(
  146. res1Rect, Resolution800x600GfxRect,
  147. selColor, BlendState.AlphaBlend);
  148. if (inRes1Rect && Input.MouseLeftButtonJustPressed)
  149. {
  150. Sound.Play(Sound.Sounds.ButtonClick);
  151. currentResolution = 1;
  152. }
  153. Rectangle res2Rect = BaseGame.CalcRectangleKeep4To3(
  154. Resolution1024x768GfxRect);
  155. res2Rect.Y += BaseGame.YToRes768(125);
  156. bool inRes2Rect = Input.MouseInBox(res2Rect);
  157. if (currentResolution == 2)
  158. BaseGame.UI.OptionsScreen.RenderOnScreen(
  159. res2Rect, Resolution1024x768GfxRect,
  160. selColor, BlendState.AlphaBlend);
  161. if (inRes2Rect && Input.MouseLeftButtonJustPressed)
  162. {
  163. Sound.Play(Sound.Sounds.ButtonClick);
  164. currentResolution = 2;
  165. }
  166. Rectangle res3Rect = BaseGame.CalcRectangleKeep4To3(
  167. Resolution1280x1024GfxRect);
  168. res3Rect.Y += BaseGame.YToRes768(125);
  169. bool inRes3Rect = Input.MouseInBox(res3Rect);
  170. if (currentResolution == 3)
  171. BaseGame.UI.OptionsScreen.RenderOnScreen(
  172. res3Rect, Resolution1280x1024GfxRect,
  173. selColor, BlendState.AlphaBlend);
  174. if (inRes3Rect && Input.MouseLeftButtonJustPressed)
  175. {
  176. Sound.Play(Sound.Sounds.ButtonClick);
  177. currentResolution = 3;
  178. }
  179. Rectangle res4Rect = BaseGame.CalcRectangleKeep4To3(
  180. ResolutionAutoGfxRect);
  181. res4Rect.Y += BaseGame.YToRes768(125);
  182. bool inRes4Rect = Input.MouseInBox(res4Rect);
  183. if (currentResolution == 4)
  184. BaseGame.UI.OptionsScreen.RenderOnScreen(
  185. res4Rect, ResolutionAutoGfxRect,
  186. selColor, BlendState.AlphaBlend);
  187. if (inRes4Rect && Input.MouseLeftButtonJustPressed)
  188. {
  189. Sound.Play(Sound.Sounds.ButtonClick);
  190. currentResolution = 4;
  191. }
  192. Rectangle fsRect = BaseGame.CalcRectangleKeep4To3(
  193. FullscreenGfxRect);
  194. fsRect.Y += BaseGame.YToRes768(125);
  195. bool inFsRect = Input.MouseInBox(fsRect);
  196. if (fullscreen)
  197. BaseGame.UI.OptionsScreen.RenderOnScreen(
  198. fsRect, FullscreenGfxRect,
  199. selColor, BlendState.AlphaBlend);
  200. if (inFsRect && Input.MouseLeftButtonJustPressed)
  201. {
  202. Sound.Play(Sound.Sounds.ButtonClick);
  203. fullscreen = !fullscreen;
  204. }
  205. Rectangle pseRect = BaseGame.CalcRectangleKeep4To3(
  206. PostScreenEffectsGfxRect);
  207. pseRect.Y += BaseGame.YToRes768(125);
  208. bool inPseRect = Input.MouseInBox(pseRect);
  209. if (usePostScreenShaders)
  210. BaseGame.UI.OptionsScreen.RenderOnScreen(
  211. pseRect, PostScreenEffectsGfxRect,
  212. selColor, BlendState.AlphaBlend);
  213. if (inPseRect && Input.MouseLeftButtonJustPressed)
  214. {
  215. Sound.Play(Sound.Sounds.ButtonClick);
  216. usePostScreenShaders = !usePostScreenShaders;
  217. }
  218. Rectangle smRect = BaseGame.CalcRectangleKeep4To3(
  219. ShadowsGfxRect);
  220. smRect.Y += BaseGame.YToRes768(125);
  221. bool inSmRect = Input.MouseInBox(smRect);
  222. if (useShadowMapping)
  223. BaseGame.UI.OptionsScreen.RenderOnScreen(
  224. smRect, ShadowsGfxRect,
  225. selColor, BlendState.AlphaBlend);
  226. if (inSmRect && Input.MouseLeftButtonJustPressed)
  227. {
  228. Sound.Play(Sound.Sounds.ButtonClick);
  229. useShadowMapping = !useShadowMapping;
  230. }
  231. Rectangle hdRect = BaseGame.CalcRectangleKeep4To3(
  232. HighDetailGfxRect);
  233. hdRect.Y += BaseGame.YToRes768(125);
  234. bool inHdRect = Input.MouseInBox(hdRect);
  235. if (useHighDetail)
  236. BaseGame.UI.OptionsScreen.RenderOnScreen(
  237. hdRect, HighDetailGfxRect,
  238. selColor, BlendState.AlphaBlend);
  239. if (inHdRect && Input.MouseLeftButtonJustPressed)
  240. {
  241. Sound.Play(Sound.Sounds.ButtonClick);
  242. useHighDetail = !useHighDetail;
  243. }
  244. #endif
  245. Rectangle soundRect = BaseGame.CalcRectangleKeep4To3(
  246. SoundGfxRect);
  247. soundRect.Y += BaseGame.YToRes768(125);
  248. if (Input.MouseInBox(soundRect))
  249. {
  250. if (Input.MouseLeftButtonJustPressed)
  251. {
  252. currentSoundVolume =
  253. (Input.MousePos.X - soundRect.X) / (float)soundRect.Width;
  254. Sound.Play(Sound.Sounds.Highlight);
  255. }
  256. }
  257. // Handel controller input
  258. if (currentOptionsNumber == 0)
  259. {
  260. if (Input.GamePadLeftJustPressed ||
  261. Input.KeyboardLeftJustPressed)
  262. {
  263. currentSoundVolume -= 0.1f;
  264. Sound.Play(Sound.Sounds.Highlight);
  265. }
  266. if (Input.GamePadRightJustPressed ||
  267. Input.KeyboardRightJustPressed)
  268. {
  269. currentSoundVolume += 0.1f;
  270. Sound.Play(Sound.Sounds.Highlight);
  271. }
  272. if (currentSoundVolume < 0)
  273. currentSoundVolume = 0;
  274. if (currentSoundVolume > 1)
  275. currentSoundVolume = 1;
  276. }
  277. // Render slider handle
  278. Rectangle gfxRect = UIRenderer.SelectionRadioButtonGfxRect;
  279. BaseGame.UI.Buttons.RenderOnScreen(new Rectangle(
  280. soundRect.X + (int)(soundRect.Width * currentSoundVolume) -
  281. BaseGame.XToRes(gfxRect.Width) / 2,
  282. soundRect.Y,
  283. BaseGame.XToRes(gfxRect.Width), BaseGame.YToRes768(gfxRect.Height)),
  284. gfxRect);
  285. Rectangle musicRect = BaseGame.CalcRectangleKeep4To3(
  286. MusicGfxRect);
  287. musicRect.Y += BaseGame.YToRes768(125);
  288. if (Input.MouseInBox(musicRect))
  289. {
  290. if (Input.MouseLeftButtonJustPressed)
  291. {
  292. currentMusicVolume =
  293. (Input.MousePos.X - musicRect.X) / (float)musicRect.Width;
  294. Sound.Play(Sound.Sounds.Highlight);
  295. }
  296. }
  297. // Handel controller input
  298. if (currentOptionsNumber == 1)
  299. {
  300. if (Input.GamePadLeftJustPressed ||
  301. Input.KeyboardLeftJustPressed)
  302. {
  303. currentMusicVolume -= 0.1f;
  304. Sound.Play(Sound.Sounds.Highlight);
  305. }
  306. if (Input.GamePadRightJustPressed ||
  307. Input.KeyboardRightJustPressed)
  308. {
  309. currentMusicVolume += 0.1f;
  310. Sound.Play(Sound.Sounds.Highlight);
  311. }
  312. if (currentMusicVolume < 0)
  313. currentMusicVolume = 0;
  314. if (currentMusicVolume > 1)
  315. currentMusicVolume = 1;
  316. }
  317. // Render slider handle
  318. BaseGame.UI.Buttons.RenderOnScreen(new Rectangle(
  319. musicRect.X + (int)(musicRect.Width * currentMusicVolume) -
  320. BaseGame.XToRes(gfxRect.Width) / 2,
  321. musicRect.Y,
  322. BaseGame.XToRes(gfxRect.Width), BaseGame.YToRes768(gfxRect.Height)),
  323. gfxRect);
  324. Sound.SetVolumes(currentSoundVolume, currentMusicVolume);
  325. Rectangle sensitivityRect = BaseGame.CalcRectangleKeep4To3(
  326. SensitivityGfxRect);
  327. sensitivityRect.Y += BaseGame.YToRes768(125);
  328. if (Input.MouseInBox(sensitivityRect))
  329. {
  330. if (Input.MouseLeftButtonJustPressed)
  331. {
  332. currentSensitivity =
  333. (Input.MousePos.X - sensitivityRect.X) /
  334. (float)sensitivityRect.Width;
  335. Sound.Play(Sound.Sounds.Highlight);
  336. }
  337. }
  338. // Handel controller input
  339. if (currentOptionsNumber == 2)
  340. {
  341. if (Input.GamePadLeftJustPressed ||
  342. Input.KeyboardLeftJustPressed)
  343. {
  344. currentSensitivity -= 0.1f;
  345. Sound.Play(Sound.Sounds.Highlight);
  346. }
  347. if (Input.GamePadRightJustPressed ||
  348. Input.KeyboardRightJustPressed)
  349. {
  350. currentSensitivity += 0.1f;
  351. Sound.Play(Sound.Sounds.Highlight);
  352. }
  353. if (currentSensitivity < 0)
  354. currentSensitivity = 0;
  355. if (currentSensitivity > 1)
  356. currentSensitivity = 1;
  357. }
  358. // Render slider handle
  359. BaseGame.UI.Buttons.RenderOnScreen(new Rectangle(
  360. sensitivityRect.X +
  361. (int)(sensitivityRect.Width * currentSensitivity) -
  362. BaseGame.XToRes(gfxRect.Width) / 2,
  363. sensitivityRect.Y,
  364. BaseGame.XToRes(gfxRect.Width), BaseGame.YToRes768(gfxRect.Height)),
  365. gfxRect);
  366. Rectangle[] lineArrowGfxRects = new Rectangle[]
  367. {
  368. Line4ArrowGfxRect,
  369. Line5ArrowGfxRect,
  370. Line6ArrowGfxRect,
  371. };
  372. for (int num = 0; num < lineArrowGfxRects.Length; num++)
  373. {
  374. Rectangle lineRect = BaseGame.CalcRectangleKeep4To3(
  375. lineArrowGfxRects[num]);
  376. lineRect.Y += BaseGame.YToRes768(125);
  377. lineRect.X -= BaseGame.XToRes(8 + (int)Math.Round(8 *
  378. Math.Sin(BaseGame.TotalTime / 0.21212f)));
  379. // Draw selection arrow
  380. if (currentOptionsNumber == num)
  381. BaseGame.UI.Buttons.RenderOnScreen(
  382. lineRect, UIRenderer.SelectionArrowGfxRect, Color.White);
  383. }
  384. // Game pad selection
  385. if (Input.GamePadUpJustPressed ||
  386. Input.KeyboardUpJustPressed)
  387. {
  388. Sound.Play(Sound.Sounds.Highlight);
  389. currentOptionsNumber = (lineArrowGfxRects.Length +
  390. currentOptionsNumber - 1) % lineArrowGfxRects.Length;
  391. }
  392. else if (Input.GamePadDownJustPressed ||
  393. Input.KeyboardDownJustPressed)
  394. {
  395. Sound.Play(Sound.Sounds.Highlight);
  396. currentOptionsNumber = (currentOptionsNumber + 1) %
  397. lineArrowGfxRects.Length;
  398. }
  399. BaseGame.UI.RenderBottomButtons(true);
  400. if (Input.KeyboardEscapeJustPressed ||
  401. Input.GamePadBJustPressed ||
  402. Input.GamePadBackJustPressed ||
  403. BaseGame.UI.backButtonPressed)
  404. {
  405. // Apply settings, for xbox only set music/sound and sensitivity!
  406. GameSettings.Default.PlayerName = currentPlayerName;
  407. switch (currentResolution)
  408. {
  409. case 0:
  410. GameSettings.Default.ResolutionWidth = 640;
  411. GameSettings.Default.ResolutionHeight = 480;
  412. break;
  413. case 1:
  414. GameSettings.Default.ResolutionWidth = 800;
  415. GameSettings.Default.ResolutionHeight = 600;
  416. break;
  417. case 2:
  418. GameSettings.Default.ResolutionWidth = 1024;
  419. GameSettings.Default.ResolutionHeight = 768;
  420. break;
  421. case 3:
  422. GameSettings.Default.ResolutionWidth = 1280;
  423. GameSettings.Default.ResolutionHeight = 1024;
  424. break;
  425. case 4:
  426. // Try to use best resolution available
  427. GameSettings.Default.ResolutionWidth = 0;
  428. GameSettings.Default.ResolutionHeight = 0;
  429. break;
  430. }
  431. GameSettings.Default.Fullscreen = fullscreen;
  432. GameSettings.Default.PostScreenEffects = usePostScreenShaders;
  433. GameSettings.Default.ShadowMapping = useShadowMapping;
  434. GameSettings.Default.HighDetail = useHighDetail;
  435. GameSettings.Default.MusicVolume = currentMusicVolume;
  436. GameSettings.Default.SoundVolume = currentSoundVolume;
  437. GameSettings.Default.ControllerSensitivity = currentSensitivity;
  438. // Save all
  439. GameSettings.Save();
  440. // Update game settings
  441. BaseGame.CheckOptionsAndPSVersion();
  442. return true;
  443. }
  444. return false;
  445. }
  446. }
  447. }