Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
MusicRider - Game1.cs

Game1.cs

Caricato da: Totem
Scarica il programma completo

  1. using System;
  2. using System.Collections.Generic;
  3. using Microsoft.Xna.Framework;
  4. using Microsoft.Xna.Framework.Graphics;
  5. using Microsoft.Xna.Framework.Input;
  6. using WaveLib;
  7. using System.IO;
  8. using System.Threading;
  9. using Microsoft.DirectX.AudioVideoPlayback;
  10. using System.Reflection;
  11.  
  12. namespace MusicRider
  13. {
  14.     public class MusicRiderGame : Microsoft.Xna.Framework.Game
  15.     {
  16.         private enum GameMode
  17.         {
  18.             FileSelection,
  19.             Playing,
  20.             GameOver,
  21.             Processing,
  22.             Menu
  23.         }
  24.  
  25.         private enum WaveMode
  26.         {
  27.             Mono = 0,
  28.             Stereo = 1
  29.         }
  30.  
  31.         GraphicsDeviceManager graphics;
  32.         SpriteBatch spriteBatch;
  33.  
  34.         SpriteFont menuItemFont, browseFont, bigFont;
  35.         GameMode currentMode;
  36.         WaveMode currentWaveMode = WaveMode.Mono;
  37.         Texture2D haloBall, haloPlayer, haloSpiral;
  38.         Texture2D logo;
  39.  
  40.         String recordsFolder = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
  41.  
  42.         public MusicRiderGame()
  43.         {
  44.             graphics = new GraphicsDeviceManager(this);
  45.             Content.RootDirectory = "Content";
  46.         }
  47.  
  48.         protected override void Initialize()
  49.         {
  50.             base.Initialize();
  51.         }
  52.  
  53.         protected override void LoadContent()
  54.         {
  55.             spriteBatch = new SpriteBatch(GraphicsDevice);
  56.             menuItemFont = Content.Load<SpriteFont>("Forte18");
  57.             browseFont = Content.Load<SpriteFont>("Arial16");
  58.             bigFont = Content.Load<SpriteFont>("Addiel44");
  59.             haloBall = Content.Load<Texture2D>("Halo3");
  60.             haloPlayer = Content.Load<Texture2D>("Halo2");
  61.             haloSpiral = Content.Load<Texture2D>("HaloSpiral");
  62.             logo = Content.Load<Texture2D>("MusicRider");
  63.             currentMode = GameMode.Menu;
  64.  
  65.             player = new Player();
  66.             player.Sprite = haloPlayer;
  67.             player.Color = Color.White;
  68.             notes = new List<GameObject>();
  69.             timedFloatingBonuses = new List<FloatingText>();
  70.  
  71.             if (File.Exists(recordsFolder + "\\records.dat"))
  72.                 records = ScoreTable.Load(recordsFolder + "\\records.dat");
  73.             if (records == null)
  74.                 records = new ScoreTable();
  75.  
  76.             Properties.Settings.Default.Reload();
  77.             Vector2 res = Properties.Settings.Default.Resolution;
  78.             this.graphics.PreferredBackBufferWidth = (int)res.X;
  79.             this.graphics.PreferredBackBufferHeight = (int)res.Y;
  80.             this.GraphicsDevice.PresentationParameters.BackBufferWidth = (int)res.X;
  81.             this.GraphicsDevice.PresentationParameters.BackBufferHeight = (int)res.Y;
  82.             this.graphics.ApplyChanges();
  83.             menuItems[1] = String.Format("Risoluzione: {0:N0}x{1:N0}", res.X, res.Y);
  84.             menuItems[3] = "Gameplay: " + GetDifficulty(Properties.Settings.Default.Difficulty);
  85.  
  86.             if (Properties.Settings.Default.Fullscreen)
  87.             {
  88.                 this.graphics.ToggleFullScreen();
  89.                 menuItems[2] = "Visualizzazione: Schermo intero";
  90.             }
  91.             else
  92.                 menuItems[2] = "Visualizzazione: Finestra";
  93.  
  94.             currentWaveMode = (WaveMode)Properties.Settings.Default.Mode;
  95.             if (currentWaveMode == WaveMode.Mono)
  96.                 menuItems[4] = "Modalità: Mono";
  97.             else
  98.                 menuItems[4] = "Modalità: Stereo";
  99.         }
  100.  
  101.         protected override void UnloadContent()
  102.         {
  103.             if (music != null)
  104.             {
  105.                 try { music.Stop(); music.Dispose(); }
  106.                 catch { }
  107.             }
  108.             foreach (String file in filesDump)
  109.                 File.Delete(file);
  110.         }
  111.  
  112.   #region "Elaborazione onda"
  113.         Wave currentWave;
  114.         FileStream audioData;
  115.         Thread temp;
  116.         String waveFileName, fasterWaveFileName, slowerWaveFileName;
  117.         float completePercentage = 0;
  118.         float speedChangeFactor = 1.0f;
  119.  
  120.         private void CreateSlowerAndFasterWaves()
  121.         {
  122.             fasterWaveFileName = String.Format("{0}\\{1} (faster).wav", Path.GetDirectoryName(waveFileName), Path.GetFileNameWithoutExtension(waveFileName));
  123.             slowerWaveFileName = String.Format("{0}\\{1} (slower).wav", Path.GetDirectoryName(waveFileName), Path.GetFileNameWithoutExtension(waveFileName));
  124.             if (File.Exists(fasterWaveFileName) && File.Exists(slowerWaveFileName))
  125.                 return;
  126.             Wave tmp = new Wave(waveFileName, false);
  127.             Int32 originalSampleRate = tmp.SampleRate;
  128.             tmp.ChangeSampleRate((int)(originalSampleRate * 0.6));
  129.             tmp.Save(slowerWaveFileName);
  130.             tmp.ChangeSampleRate((int)(originalSampleRate * 1.4));
  131.             tmp.Save(fasterWaveFileName);
  132.             tmp.Dispose();
  133.             filesDump.Add(fasterWaveFileName);
  134.             filesDump.Add(slowerWaveFileName);
  135.         }
  136.  
  137.         private FileStream CreateMonoAudioFile(String dataFilePath)
  138.         {
  139.             FileStream stream = new FileStream(dataFilePath, FileMode.Create);
  140.             BinaryWriter writer = new BinaryWriter(stream);
  141.             Int32 duration = (int)Math.Floor(currentWave.Duration);
  142.             Int32 minIntensity, maxIntensity, minPeeksNumber, maxPeeksNumber;
  143.  
  144.             maxIntensity = maxPeeksNumber = 0;
  145.             minIntensity = minPeeksNumber = Int32.MaxValue;
  146.             writer.Write((Int32)0); //minimo intensità
  147.             writer.Write((Int32)0); //massimo "
  148.             writer.Write((Int32)0); //minimo picchi
  149.             writer.Write((Int32)0); //massimo picchi
  150.             for (Int32 second = 0; second < duration; second++)
  151.             {
  152.                 Int32 prev1, prev2, cur;
  153.                 List<Int32> peeks = new List<Int32>();
  154.  
  155.                 prev1 = Math.Abs((currentWave.ReadSample())[0]);
  156.                 prev2 = Math.Abs((currentWave.ReadSample())[0]);
  157.                 for (Int32 i = 0; i < currentWave.SampleRate - 2; i++)
  158.                 {
  159.                     cur = Math.Abs((currentWave.ReadSample())[0]);
  160.                     if ((prev2 > prev1) && (prev2 > cur))
  161.                         peeks.Add(prev2);
  162.                     prev1 = prev2;
  163.                     prev2 = cur;
  164.                 }
  165.  
  166.                 if (peeks.Count > maxPeeksNumber)
  167.                     maxPeeksNumber = peeks.Count;
  168.                 if ((peeks.Count > 0) && (peeks.Count < minPeeksNumber))
  169.                     minPeeksNumber = peeks.Count;
  170.  
  171.                 Int32 avg = 0;
  172.                 if (peeks.Count > 0)
  173.                 {
  174.                     foreach (Int32 i in peeks)
  175.                         avg += i;
  176.                     avg /= peeks.Count;
  177.                     if (avg < minIntensity)
  178.                         minIntensity = avg;
  179.                     if (avg > maxIntensity)
  180.                         maxIntensity = avg;
  181.                 }
  182.  
  183.                 writer.Write((Int32)peeks.Count);
  184.                 writer.Write((Int32)avg);
  185.                 completePercentage = ((float)second / duration) * 100f;
  186.             }
  187.             writer.Flush();
  188.             writer.BaseStream.Position = 0;
  189.             writer.Write(minIntensity);
  190.             writer.Write(maxIntensity);
  191.             writer.Write(minPeeksNumber);
  192.             writer.Write(maxPeeksNumber);
  193.             writer.Flush();
  194.             writer = null;
  195.             stream.Position = 0;
  196.             return stream;
  197.         }
  198.  
  199.         private FileStream CreateStereoAudioFile(String dataFilePath)
  200.         {
  201.             FileStream stream = new FileStream(dataFilePath, FileMode.Create);
  202.             BinaryWriter writer = new BinaryWriter(stream);
  203.             Int32 duration = (int)Math.Floor(currentWave.Duration);
  204.             Int32 minIntensity, maxIntensity, minPeeksNumber, maxPeeksNumber;
  205.  
  206.             maxIntensity = maxPeeksNumber = 0;
  207.             minIntensity = minPeeksNumber = Int32.MaxValue;
  208.             writer.Write((byte)'s');
  209.             writer.Write((byte)'t');
  210.             writer.Write((byte)'e');
  211.             writer.Write((byte)'r');
  212.             writer.Write((Int32)0); //minimo intensità
  213.             writer.Write((Int32)0); //massimo "
  214.             writer.Write((Int32)0); //minimo picchi
  215.             writer.Write((Int32)0); //massimo picchi
  216.             for (Int32 second = 0; second < duration; second++)
  217.             {
  218.                 Int32[] prev1, prev2, cur;
  219.                 List<Int32> peeksLeft = new List<Int32>();
  220.                 List<Int32> peeksRight = new List<Int32>();
  221.  
  222.                 prev1 = currentWave.ReadSample();
  223.                 prev2 = currentWave.ReadSample();
  224.                 for (Int32 i = 0; i < currentWave.SampleRate - 2; i++)
  225.                 {
  226.                     cur = currentWave.ReadSample();
  227.                     if ((prev2[0] > prev1[0]) && (prev2[0] > cur[0]))
  228.                         peeksLeft.Add(prev2[0]);
  229.                     if ((prev2[1] > prev1[1]) && (prev2[1] > cur[1]))
  230.                         peeksRight.Add(prev2[1]);
  231.                     prev1 = prev2;
  232.                     prev2 = cur;
  233.                 }
  234.  
  235.                 if (peeksLeft.Count > maxPeeksNumber)
  236.                     maxPeeksNumber = peeksLeft.Count;
  237.                 if (peeksRight.Count > maxPeeksNumber)
  238.                     maxPeeksNumber = peeksRight.Count;
  239.                 if ((peeksLeft.Count > 0) && (peeksLeft.Count < minPeeksNumber))
  240.                     minPeeksNumber = peeksLeft.Count;
  241.                 if ((peeksRight.Count > 0) && (peeksRight.Count < minPeeksNumber))
  242.                     minPeeksNumber = peeksRight.Count;
  243.  
  244.                 Int32 avg = 0;
  245.                 if (peeksLeft.Count > 0)
  246.                 {
  247.                     foreach (Int32 i in peeksLeft)
  248.                         avg += i;
  249.                     avg /= peeksLeft.Count;
  250.                     if (avg < minIntensity)
  251.                         minIntensity = avg;
  252.                     if (avg > maxIntensity)
  253.                         maxIntensity = avg;
  254.                 }
  255.                 writer.Write((Int32)peeksLeft.Count);
  256.                 writer.Write((Int32)avg);
  257.  
  258.                 avg = 0;
  259.                 if (peeksRight.Count > 0)
  260.                 {
  261.                     foreach (Int32 i in peeksRight)
  262.                         avg += i;
  263.                     avg /= peeksRight.Count;
  264.                     if (avg < minIntensity)
  265.                         minIntensity = avg;
  266.                     if (avg > maxIntensity)
  267.                         maxIntensity = avg;
  268.                 }
  269.                 writer.Write((Int32)peeksRight.Count);
  270.                 writer.Write((Int32)avg);
  271.  
  272.                 peeksLeft.Clear();
  273.                 peeksRight.Clear();
  274.                 peeksLeft = null;
  275.                 peeksRight = null;
  276.                 completePercentage = ((float)second / duration) * 100f;
  277.             }
  278.             writer.Flush();
  279.             writer.BaseStream.Position = 4;
  280.             writer.Write(minIntensity);
  281.             writer.Write(maxIntensity);
  282.             writer.Write(minPeeksNumber);
  283.             writer.Write(maxPeeksNumber);
  284.             writer.Flush();
  285.             writer = null;
  286.             stream.Position = 0;
  287.             return stream;
  288.         }
  289.  
  290.         private void ProcessWave()
  291.         {
  292.             completePercentage = 0f;
  293.             String dataFilePath = Path.GetDirectoryName(currentWave.OriginalFileName) + "\\" + Path.GetFileNameWithoutExtension(currentWave.OriginalFileName) + ".ad";
  294.             waveFileName = currentWave.OriginalFileName;
  295.             if (File.Exists(dataFilePath))
  296.             {
  297.                 if (audioData != null)
  298.                 {
  299.                     try { audioData.Close(); }
  300.                     catch { }
  301.                 }
  302.                 audioData = File.Open(dataFilePath, FileMode.Open);
  303.                 completePercentage = 50f;
  304.                 CreateSlowerAndFasterWaves();
  305.                 completePercentage = 100f;
  306.                 return;
  307.             }
  308.  
  309.             if ((currentWaveMode == WaveMode.Mono) ||
  310.                 (currentWaveMode == WaveMode.Stereo && currentWave.ChannelsNumber < 2))
  311.                 audioData = CreateMonoAudioFile(dataFilePath);
  312.             else
  313.                 audioData = CreateStereoAudioFile(dataFilePath);
  314.            
  315.             audioData.Position = 0;
  316.             currentWave.Dispose();
  317.             CreateSlowerAndFasterWaves();
  318.             completePercentage = 100f;
  319.         }
  320.  
  321.         private void ProcessWaveAsync()
  322.         {
  323.             temp = new Thread(ProcessWave);
  324.             temp.Start();
  325.         }
  326.  
  327.    #endregion
  328.  
  329.    #region "Gestione Input"
  330.         bool keyPressed = false;
  331.         bool buttonPressed = false;
  332.         Vector2[] screenFormats = {
  333.             new Vector2(800, 600),
  334.             new Vector2(1024, 768),
  335.             new Vector2(1152, 864),
  336.             new Vector2(1280, 800),
  337.             new Vector2(1280, 1024),
  338.             new Vector2(1600, 1200),
  339.             new Vector2(1680, 1050)};
  340.         String[] menuItems = { "Seleziona file", "Risoluzione: 800x600", "Visualizzazione: Schermo intero", "Gameplay: Normale", "Modalità: Mono", "Score Table", "Esci" };
  341.         String[] gameOverMenuItems = { "Ritenta", "Score Table", "Classifica online (NYI)", "Ritorna al menu" };
  342.         Int32 selectedIndex = 0;
  343.         Int32 selectedSubIndex = 0;
  344.         List<String> wavesList;
  345.         String currentDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic);
  346.  
  347.         private void ProcessMenuInput()
  348.         {
  349.             KeyboardState kState = Keyboard.GetState();
  350.             if (kState.IsKeyDown(Keys.Up) && !keyPressed)
  351.             {
  352.                 selectedIndex--;
  353.                 if (selectedIndex < 0)
  354.                     selectedIndex = 0;
  355.                 keyPressed = true;
  356.             }
  357.             if (kState.IsKeyDown(Keys.Down) && !keyPressed)
  358.             {
  359.                 selectedIndex++;
  360.                 if (selectedIndex > menuItems.Length - 1)
  361.                     selectedIndex = menuItems.Length - 1;
  362.                 keyPressed = true;
  363.             }
  364.             if (kState.IsKeyDown(Keys.Left) && !keyPressed)
  365.             {
  366.                 switch (selectedIndex)
  367.                 {
  368.                     case 1:
  369.                         selectedSubIndex--;
  370.                         if (selectedSubIndex < 0)
  371.                             selectedSubIndex = 0;
  372.                         menuItems[1] = String.Format("Risoluzione: {0:N0}x{1:N0}", screenFormats[selectedSubIndex].X, screenFormats[selectedSubIndex].Y);
  373.                         keyPressed = true;
  374.                         break;
  375.                     case 3:
  376.                         selectedSubIndex--;
  377.                         if (selectedSubIndex < 0)
  378.                             selectedSubIndex = 0;
  379.                         keyPressed = true;
  380.                         menuItems[3] = "Gameplay: " + GetDifficulty(selectedSubIndex);
  381.                         break;
  382.                 }
  383.             }
  384.             if (kState.IsKeyDown(Keys.Right) && !keyPressed)
  385.             {
  386.                 switch(selectedIndex)
  387.                 {
  388.                     case 1:
  389.                         selectedSubIndex++;
  390.                         if (selectedSubIndex > screenFormats.Length - 1)
  391.                             selectedSubIndex = screenFormats.Length - 1;
  392.                         menuItems[1] = String.Format("Risoluzione: {0:N0}x{1:N0}", screenFormats[selectedSubIndex].X, screenFormats[selectedSubIndex].Y);
  393.                         keyPressed = true;
  394.                         break;
  395.                     case 3:
  396.                         selectedSubIndex++;
  397.                         if (selectedSubIndex > 6)
  398.                             selectedSubIndex = 6;
  399.                         menuItems[3] = "Gameplay: " + GetDifficulty(selectedSubIndex);
  400.                         keyPressed = true;
  401.                         break;
  402.                 }
  403.             }
  404.             if (kState.IsKeyDown(Keys.Enter) && !keyPressed)
  405.             {
  406.                 switch (selectedIndex)
  407.                 {
  408.                     case 0:
  409.                         currentMode = GameMode.FileSelection;
  410.                         break;
  411.                     case 1:
  412.                         Properties.Settings.Default.Resolution = screenFormats[selectedSubIndex];
  413.                         Properties.Settings.Default.Save();
  414.                         this.graphics.PreferredBackBufferWidth = (int)screenFormats[selectedSubIndex].X;
  415.                         this.graphics.PreferredBackBufferHeight = (int)screenFormats[selectedSubIndex].Y;
  416.                         this.GraphicsDevice.PresentationParameters.BackBufferWidth = (int)screenFormats[selectedSubIndex].X;
  417.                         this.GraphicsDevice.PresentationParameters.BackBufferHeight = (int)screenFormats[selectedSubIndex].Y;
  418.                         this.graphics.ApplyChanges();
  419.                         break;
  420.                     case 2:
  421.                         this.graphics.ToggleFullScreen();
  422.                         if (this.graphics.IsFullScreen)
  423.                             menuItems[2] = "Visualizzazione: Schermo intero";
  424.                         else
  425.                             menuItems[2] = "Visualizzazione: Finestra";
  426.                         Properties.Settings.Default.Fullscreen = this.graphics.IsFullScreen;
  427.                         Properties.Settings.Default.Save();
  428.                         break;
  429.                     case 3:
  430.                         Properties.Settings.Default.Difficulty = selectedSubIndex;
  431.                         Properties.Settings.Default.Save();
  432.                         break;
  433.                     case 4:
  434.                         currentWaveMode = 1 - currentWaveMode;
  435.                         if (currentWaveMode == WaveMode.Mono)
  436.                             menuItems[4] = "Modalità: Mono";
  437.                         else
  438.                             menuItems[4] = "Modalità: Stereo";
  439.                         Properties.Settings.Default.Mode = (int)currentWaveMode;
  440.                         Properties.Settings.Default.Save();
  441.                         break;
  442.                     case 5:
  443.                         records.GenerateHtmlTable(recordsFolder + "\\records.html");
  444.                         System.Diagnostics.Process.Start(recordsFolder + "\\records.html");
  445.                         break;
  446.                     case 6:
  447.                         this.Exit();
  448.                         break;
  449.                 }
  450.                 selectedIndex = 0;
  451.                 keyPressed = true;
  452.                 return;
  453.             }
  454.             if (kState.IsKeyUp(Keys.Up) && kState.IsKeyUp(Keys.Down) && kState.IsKeyUp(Keys.Enter)
  455.                 && kState.IsKeyUp(Keys.Left) && kState.IsKeyUp(Keys.Right))
  456.                 keyPressed = false;
  457.         }
  458.  
  459.         public static String GetDifficulty(Int32 index)
  460.         {
  461.             switch (index)
  462.             {
  463.                 case 0: return "Molto semplice";
  464.                 case 1: return "Semplice";
  465.                 case 2: return "Normale";
  466.                 case 3: return "Difficile";
  467.                 case 4: return "Molto difficile";
  468.                 case 5: return "Impossibile";
  469.                 case 6: return "Custom";
  470.             }
  471.             return "???";
  472.         }
  473.  
  474.         private void ProcessFileSelectionInput()
  475.         {
  476.             KeyboardState kState = Keyboard.GetState();
  477.             if (wavesList == null)
  478.             {
  479.                 wavesList = new List<String>();
  480.                 wavesList.AddRange(Directory.GetDirectories(currentDirectory));
  481.                 wavesList.AddRange(Directory.GetFiles(currentDirectory, "*.wav", SearchOption.TopDirectoryOnly));
  482.             }
  483.             if (kState.IsKeyDown(Keys.Up) && !keyPressed)
  484.             {
  485.                 selectedIndex--;
  486.                 if (selectedIndex < 0)
  487.                     selectedIndex = 0;
  488.                 keyPressed = true;
  489.             }
  490.             if (kState.IsKeyDown(Keys.Down) && !keyPressed)
  491.             {
  492.                 selectedIndex++;
  493.                 if (selectedIndex > wavesList.Count - 1)
  494.                     selectedIndex = wavesList.Count - 1;
  495.                 keyPressed = true;
  496.             }
  497.             if (kState.IsKeyDown(Keys.Enter) && !keyPressed)
  498.             {
  499.                 try
  500.                 {
  501.                     if (File.Exists(wavesList[selectedIndex]))
  502.                     {
  503.                         currentWave = new Wave(wavesList[selectedIndex], false);
  504.                         currentMode = GameMode.Processing;
  505.                         ProcessWaveAsync();
  506.                     }
  507.                     else if (Directory.Exists(wavesList[selectedIndex]))
  508.                     {
  509.                         currentDirectory = wavesList[selectedIndex];
  510.                         wavesList.Clear();
  511.                         wavesList.Add("Parent");
  512.                         wavesList.AddRange(Directory.GetDirectories(currentDirectory));
  513.                         wavesList.AddRange(Directory.GetFiles(currentDirectory, "*.wav", SearchOption.TopDirectoryOnly));
  514.                         selectedIndex = 0;
  515.                     }
  516.                     else if (wavesList[selectedIndex] == "Parent")
  517.                     {
  518.                         currentDirectory = currentDirectory.Remove(currentDirectory.LastIndexOf("\\"));
  519.                         wavesList.Clear();
  520.                         if (currentDirectory != Environment.GetFolderPath(Environment.SpecialFolder.MyMusic))
  521.                             wavesList.Add("Parent");
  522.                         wavesList.AddRange(Directory.GetDirectories(currentDirectory));
  523.                         wavesList.AddRange(Directory.GetFiles(currentDirectory, "*.wav", SearchOption.TopDirectoryOnly));
  524.                         selectedIndex = 0;
  525.                     }
  526.                 }
  527.                 catch
  528.                 {
  529.                     wavesList.RemoveAt(selectedIndex);
  530.                 }
  531.                 keyPressed = true;
  532.             }
  533.             if (kState.IsKeyDown(Keys.Escape))
  534.             {
  535.                 keyPressed = true;
  536.                 currentMode = GameMode.Menu;
  537.             }
  538.             if (kState.IsKeyUp(Keys.Up) && kState.IsKeyUp(Keys.Down) && kState.IsKeyUp(Keys.Enter))
  539.                 keyPressed = false;
  540.         }
  541.  
  542.         private void ProcessGameInput(GameTime gameTime)
  543.         {
  544.             MouseState mState = Mouse.GetState();
  545.             KeyboardState kState = Keyboard.GetState();
  546.             player.Position = new Vector2(mState.X, mState.Y);
  547.             if (kState.IsKeyDown(Keys.Escape))
  548.             {
  549.                 keyPressed = true;
  550.                 currentMode = GameMode.Menu;
  551.                 notes.Clear();
  552.                 notesToSpawn.Clear();
  553.                 if (music != null)
  554.                 {
  555.                     music.Stop();
  556.                     music.Dispose();
  557.                 }
  558.             }
  559.             if (mState.LeftButton == ButtonState.Pressed && !buttonPressed && availableMagnets > 0)
  560.             {
  561.                 magnetEnabled = true;
  562.                 magnetStartTime = gameTime.TotalGameTime.TotalSeconds;
  563.                 timedFloatingBonuses.Add(new FloatingText(player.Position,
  564.                     "Magnet!", player.Color, gameTime.TotalGameTime.TotalSeconds));
  565.                 availableMagnets--;
  566.                 buttonPressed = true;
  567.             }
  568.             if (mState.RightButton == ButtonState.Pressed && !buttonPressed && availableAllColors > 0)
  569.             {
  570.                 foreach (GameObject note in notes)
  571.                     note.Color = player.Color;
  572.                 availableAllColors--;
  573.                 buttonPressed = true;
  574.             }
  575.             if (mState.LeftButton == ButtonState.Released && mState.RightButton == ButtonState.Released)
  576.                 buttonPressed = false;
  577.         }
  578.  
  579.         private void ProcessGameOverInput()
  580.         {
  581.             KeyboardState kState = Keyboard.GetState();
  582.             if (kState.IsKeyDown(Keys.Up) && !keyPressed)
  583.             {
  584.                 selectedIndex--;
  585.                 if (selectedIndex < 0)
  586.                     selectedIndex = 0;
  587.                 keyPressed = true;
  588.             }
  589.             if (kState.IsKeyDown(Keys.Down) && !keyPressed)
  590.             {
  591.                 selectedIndex++;
  592.                 if (selectedIndex > gameOverMenuItems.Length - 1)
  593.                     selectedIndex = gameOverMenuItems.Length - 1;
  594.                 keyPressed = true;
  595.             }
  596.             if (kState.IsKeyDown(Keys.Enter) && !keyPressed)
  597.             {
  598.                 switch (selectedIndex)
  599.                 {
  600.                     case 0:
  601.                         StartPlaying();
  602.                         break;
  603.                     case 1:
  604.                         records.GenerateHtmlTable(recordsFolder + "\\records.html");
  605.                         System.Diagnostics.Process.Start(recordsFolder + "\\records.html");
  606.                         break;
  607.                     case 2:
  608.                         // todo
  609.                         break;
  610.                     case 3:
  611.                         currentMode = GameMode.Menu;
  612.                         notes.Clear();
  613.                         notesToSpawn.Clear();
  614.                         try
  615.                         {
  616.                             if (music != null)
  617.                             {
  618.                                 music.Stop();
  619.                                 music.Dispose();
  620.                                 audioData.Close();
  621.                             }
  622.                         }
  623.                         catch { }
  624.                         finally
  625.                         {
  626.                             audioData.Close();
  627.                         }
  628.                         break;
  629.                 }
  630.                 selectedIndex = 0;
  631.                 keyPressed = true;
  632.                 return;
  633.             }
  634.             if (kState.IsKeyUp(Keys.Up) && kState.IsKeyUp(Keys.Down) && kState.IsKeyUp(Keys.Enter))
  635.                 keyPressed = false;
  636.         }
  637.    #endregion
  638.  
  639.    #region "Gestione gioco"
  640.         // Discarica (file temporanei da eliminare)
  641.         List<String> filesDump = new List<String>();
  642.  
  643.         // Generale
  644.         Audio music;
  645.         Random rnd = new Random(DateTime.Now.Millisecond);
  646.  
  647.         // Note
  648.         List<GameObject> notesToSpawn;
  649.         List<GameObject> notes;
  650.         Player player;
  651.         public Int32 maxNotesPerSecond = 30;
  652.  
  653.         // Punteggi
  654.         Int64 score = 0;
  655.         Color scoreColor = Color.White;
  656.         Int32 baseScaleBonus = 100;
  657.         Int32 baseSpeedBonus = 10;
  658.         float baseVariationBonus = 2;
  659.         public float baseNegativeBonus = -5;
  660.         float multiplier = 1.0f;
  661.         public float multiplierIncrement = 0.1f;
  662.         public float baseNegativeMultiplier = 0.5f;
  663.         ScoreTable records;
  664.  
  665.         // Altri parametri
  666.         public float baseYSpeed = 800f;
  667.         public double movingNotesPercentage = 0.2d;
  668.         public double shrinkingNotesPercentage = 0.2d;
  669.         public double badNotesPercentage = 0.2d;
  670.  
  671.         // Powerups
  672.         bool magnetEnabled = false;
  673.         double magnetStartTime = 0;
  674.         double magnetDuration = 10d;
  675.         public Int32 numberOfMagnets = 2;
  676.         public Int32 numberOfAllColors = 2;
  677.         Int32 availableMagnets = 2;
  678.         Int32 availableAllColors = 2;
  679.  
  680.         // Spiral
  681.         bool spiralAppeared = true;
  682.         double spiralApparitionPercent = 0.0005d;
  683.         double spiralApparitionTime = 0;
  684.         GameObject spiral;
  685.  
  686.         // Dati partita
  687.         Int32 numberOfBadNotes, numberOfCaughtBadNotes, numberOfNotes, numberOfCaughtNotes;
  688.  
  689.         // Testo scorrevole
  690.         List<FloatingText> timedFloatingBonuses;
  691.         float secondsBeforeTextElapses = 2.5f;
  692.  
  693.         private void SpiralCreationEvent(GameObject obj)
  694.         {
  695.             double pos = music.CurrentPosition;
  696.             music.Stop();
  697.             music.Dispose();
  698.             if (rnd.NextDouble() < 0.5d)
  699.             {
  700.                 music = Audio.FromFile(fasterWaveFileName);
  701.                 speedChangeFactor = 1.4f;
  702.             }
  703.             else
  704.             {
  705.                 music = Audio.FromFile(slowerWaveFileName);
  706.                 speedChangeFactor = 0.6f;
  707.             }
  708.             foreach (GameObject note in notesToSpawn)
  709.                 note.Speed *= speedChangeFactor;
  710.             music.CurrentPosition = pos / speedChangeFactor;
  711.             music.Play();
  712.         }
  713.  
  714.         private void ApplyDifficulty()
  715.         {
  716.             switch (Properties.Settings.Default.Difficulty)
  717.             {
  718.                 case 0 :
  719.                     baseNegativeBonus = 0;
  720.                     multiplierIncrement = 0.5f;
  721.                     baseNegativeMultiplier = 1.0f;
  722.                     maxNotesPerSecond = 10;
  723.                     baseYSpeed = 350f;
  724.                     movingNotesPercentage = 0.1f;
  725.                     shrinkingNotesPercentage = 0.1f;
  726.                     badNotesPercentage = 0.05f;
  727.                     numberOfAllColors = 3;
  728.                     numberOfMagnets = 3;
  729.                     break;
  730.                 case 1:
  731.                     baseNegativeBonus = -2;
  732.                     multiplierIncrement = 0.3f;
  733.                     baseNegativeMultiplier = 0.7f;
  734.                     maxNotesPerSecond = 16;
  735.                     baseYSpeed = 400f;
  736.                     movingNotesPercentage = 0.15f;
  737.                     shrinkingNotesPercentage = 0.15f;
  738.                     badNotesPercentage = 0.08f;
  739.                     numberOfAllColors = 3;
  740.                     numberOfMagnets = 2;
  741.                     break;
  742.                 case 2:
  743.                     baseNegativeBonus = -4;
  744.                     multiplierIncrement = 0.15f;
  745.                     baseNegativeMultiplier = 0.5f;
  746.                     maxNotesPerSecond = 19;
  747.                     baseYSpeed = 500f;
  748.                     movingNotesPercentage = 0.2f;
  749.                     shrinkingNotesPercentage = 0.2f;
  750.                     badNotesPercentage = 0.09f;
  751.                     numberOfAllColors = 2;
  752.                     numberOfMagnets = 2;
  753.                     break;
  754.                 case 3:
  755.                     baseNegativeBonus = -6;
  756.                     multiplierIncrement = 0.1f;
  757.                     baseNegativeMultiplier = 0.3f;
  758.                     maxNotesPerSecond = 24;
  759.                     baseYSpeed = 600f;
  760.                     movingNotesPercentage = 0.25f;
  761.                     shrinkingNotesPercentage = 0.25f;
  762.                     badNotesPercentage = 0.1f;
  763.                     numberOfAllColors = 2;
  764.                     numberOfMagnets = 1;
  765.                     break;
  766.                 case 4:
  767.                     baseNegativeBonus = -7;
  768.                     multiplierIncrement = 0.05f;
  769.                     baseNegativeMultiplier = 0.1f;
  770.                     maxNotesPerSecond = 27;
  771.                     baseYSpeed = 700f;
  772.                     movingNotesPercentage = 0.3f;
  773.                     shrinkingNotesPercentage = 0.3f;
  774.                     badNotesPercentage = 0.11f;
  775.                     numberOfAllColors = 1;
  776.                     numberOfMagnets = 1;
  777.                     break;
  778.                 case 5:
  779.                     baseNegativeBonus = -9;
  780.                     multiplierIncrement = 0.05f;
  781.                     baseNegativeMultiplier = 0f;
  782.                     maxNotesPerSecond = 32;
  783.                     baseYSpeed = 800f;
  784.                     movingNotesPercentage = 0.3f;
  785.                     shrinkingNotesPercentage = 0.3f;
  786.                     badNotesPercentage = 0.13f;
  787.                     numberOfAllColors = 0;
  788.                     numberOfMagnets = 0;
  789.                     break;
  790.                 case 6:
  791.                     StreamReader reader = new StreamReader(recordsFolder + "\\custom_diff.ini");
  792.                     String line;
  793.                     FieldInfo[] fields = this.GetType().GetFields();
  794.                     // regex per un ini? non ho voglia
  795.                     do {
  796.                         line = reader.ReadLine();
  797.                         line = line.Trim();
  798.                         if (line.StartsWith("[") || String.IsNullOrEmpty(line) || line.StartsWith("#") || !line.Contains("="))
  799.                             continue;
  800.                         if (line.IndexOf("#") > -1)
  801.                             line = line.Remove(line.IndexOf("#"));
  802.                         String[] parts = line.Split('=');
  803.                         parts[0] = parts[0].Trim();
  804.                         parts[1] = parts[1].Trim();
  805.                         foreach (FieldInfo f in fields)
  806.                         {
  807.                             try
  808.                             {
  809.                                 if (parts[0] == f.Name)
  810.                                     f.SetValue(this, Convert.ChangeType(parts[1], f.FieldType));
  811.                             }
  812.                             catch { }
  813.                         }
  814.                     } while (!reader.EndOfStream);
  815.                     reader.Close();
  816.                     break;
  817.             }
  818.         }
  819.  
  820.         private void StartPlaying()
  821.         {
  822.             currentMode = GameMode.Playing;
  823.             score = 0;
  824.             scoreColor = Color.White;
  825.             availableMagnets = numberOfMagnets;
  826.             availableAllColors = numberOfAllColors;
  827.             multiplier = 1.0f;
  828.             magnetEnabled = false;
  829.             player.Position = new Vector2(this.graphics.PreferredBackBufferWidth / 2 - player.Sprite.Width / 2,
  830.                 this.graphics.PreferredBackBufferHeight - 100);
  831.             ApplyDifficulty();
  832.             GenerateNotes();
  833.             music = Audio.FromFile(waveFileName);
  834.             music.Play();
  835.         }
  836.  
  837.         private GameObject GenerateOneMonoNote(float peeksPercent, float notesPercent)
  838.         {
  839.             GameObject n = new GameObject();
  840.             Int32 x;
  841.             n.Sprite = haloBall;
  842.             x = 35 + (int)(peeksPercent * (this.graphics.PreferredBackBufferWidth - 70));
  843.             n.Position = new Vector2(x + (float)((rnd.NextDouble() - 0.5d) * 50), 40);
  844.             n.Speed = Vector2.UnitY * notesPercent * baseYSpeed;
  845.             n.Speed += Vector2.UnitX * (float)((rnd.NextDouble() - 0.5d) * 30);
  846.             n.Scale = 0.7f + (float)(rnd.NextDouble() * 0.4);
  847.  
  848.             if (rnd.NextDouble() < shrinkingNotesPercentage)
  849.                 n.Variation = GameObject.HarmonicScaleVariation;
  850.             else if (rnd.NextDouble() < movingNotesPercentage)
  851.                 n.Variation = GameObject.HarmonicXVariation;
  852.  
  853.             if (rnd.NextDouble() > (1.0f - badNotesPercentage))
  854.             {
  855.                 n.Color = Color.Red;
  856.                 numberOfBadNotes++;
  857.             }
  858.             else
  859.                 n.Color = new Color((byte)rnd.Next(50, 256), (byte)rnd.Next(50, 256), (byte)rnd.Next(50, 256));
  860.  
  861.             return n;
  862.         }
  863.  
  864.         private GameObject GenerateOneStereoNote(float peeksPercent, float notesPercent, bool isLeft)
  865.         {
  866.             GameObject n = new GameObject();
  867.             Int32 y;
  868.             n.Sprite = haloBall;
  869.             y = 35 + (int)(peeksPercent * (this.graphics.PreferredBackBufferHeight - 70));
  870.             if (isLeft)
  871.             {
  872.                 n.Position = new Vector2(40, y + (float)((rnd.NextDouble() - 0.5d) * 50));
  873.                 n.Speed = Vector2.UnitX * notesPercent * baseYSpeed;
  874.             }
  875.             else
  876.             {
  877.                 n.Position = new Vector2(this.graphics.PreferredBackBufferWidth - 40, y + (float)((rnd.NextDouble() - 0.5d) * 50));
  878.                 n.Speed = -Vector2.UnitX * notesPercent * baseYSpeed;
  879.             }
  880.             n.Speed += Vector2.UnitY * (float)((rnd.NextDouble() - 0.5d) * 30);
  881.             n.Scale = 0.7f + (float)(rnd.NextDouble() * 0.4);
  882.  
  883.             if (rnd.NextDouble() < shrinkingNotesPercentage)
  884.                 n.Variation = GameObject.HarmonicScaleVariation;
  885.             else if (rnd.NextDouble() < movingNotesPercentage)
  886.                 n.Variation = GameObject.HarmonicYVariation;
  887.  
  888.             if (rnd.NextDouble() > (1.0f - badNotesPercentage))
  889.             {
  890.                 n.Color = Color.Red;
  891.                 numberOfBadNotes++;
  892.             }
  893.             else
  894.                 n.Color = new Color((byte)rnd.Next(50, 256), (byte)rnd.Next(50, 256), (byte)rnd.Next(50, 256));
  895.  
  896.             return n;
  897.         }
  898.  
  899.         private void GenerateNotes()
  900.         {
  901.             BinaryReader reader = new BinaryReader(audioData);
  902.             Int32 minIntensity, maxIntensity, minPeeksNumber, maxPeeksNumber;
  903.             Int32 second = 0;
  904.             Char[] chars;
  905.             bool isStereo = false;
  906.  
  907.             chars = reader.ReadChars(4);
  908.             if (chars[0] == 's' && chars[1] == 't' && chars[2] == 'e' && chars[3] == 'r')
  909.                 isStereo = true;
  910.             else
  911.                 reader.BaseStream.Position = 0;
  912.  
  913.             minIntensity = reader.ReadInt32();
  914.             maxIntensity = reader.ReadInt32();
  915.             minPeeksNumber = reader.ReadInt32();
  916.             maxPeeksNumber = reader.ReadInt32();
  917.  
  918.             if (notesToSpawn == null)
  919.                 notesToSpawn = new List<GameObject>();
  920.             notesToSpawn.Clear();
  921.             notes.Clear();
  922.             numberOfCaughtNotes = 0;
  923.             numberOfBadNotes = 0;
  924.             numberOfCaughtBadNotes = 0;
  925.             do
  926.             {
  927.                 Int32 peeksCount, avg;
  928.                 Int32 notesNumber;
  929.                 peeksCount = reader.ReadInt32();
  930.                 avg = reader.ReadInt32();
  931.                 notesNumber = (int)(((float)(avg - minIntensity) / (maxIntensity - minIntensity)) * maxNotesPerSecond);
  932.                 notesNumber = (int)MathHelper.Clamp(notesNumber, 1, maxNotesPerSecond);
  933.                 for (Int32 i = 0; i < notesNumber; i++)
  934.                 {
  935.                     GameObject n;
  936.                     if ((currentWaveMode == WaveMode.Mono) || (!isStereo))
  937.                         n = GenerateOneMonoNote((float)(peeksCount - minPeeksNumber) / (maxPeeksNumber - minPeeksNumber), (float)notesNumber / maxNotesPerSecond);
  938.                     else
  939.                         n = GenerateOneStereoNote((float)(peeksCount - minPeeksNumber) / (maxPeeksNumber - minPeeksNumber), (float)notesNumber / maxNotesPerSecond, true);
  940.                     n.SpawnTime = (double)second + ((double)i / notesNumber);
  941.                     notesToSpawn.Add(n);
  942.                 }
  943.                 if (isStereo)
  944.                 {
  945.                     peeksCount = reader.ReadInt32();
  946.                     avg = reader.ReadInt32();
  947.                     if (currentWaveMode == WaveMode.Stereo)
  948.                     {
  949.                         notesNumber = (int)(((float)(avg - minIntensity) / (maxIntensity - minIntensity)) * maxNotesPerSecond);
  950.                         notesNumber = (int)MathHelper.Clamp(notesNumber, 1, maxNotesPerSecond);
  951.                         for (Int32 i = 0; i < notesNumber; i++)
  952.                         {
  953.                             GameObject n;
  954.                             n = GenerateOneStereoNote((float)(peeksCount - minPeeksNumber) / (maxPeeksNumber - minPeeksNumber), (float)notesNumber / maxNotesPerSecond, false);
  955.                             n.SpawnTime = (double)second + ((double)i / notesNumber);
  956.                             notesToSpawn.Add(n);
  957.                         }
  958.                     }
  959.                 }
  960.                 second++;
  961.             } while (reader.BaseStream.Position < reader.BaseStream.Length - 1);
  962.             numberOfNotes = notesToSpawn.Count;
  963.             reader = null;
  964.             audioData.Position = 0;
  965.         }
  966.  
  967.         private void SpawnNotes()
  968.         {
  969.             List<GameObject> toDel = new List<GameObject>();
  970.             foreach (GameObject go in notesToSpawn)
  971.             {
  972.                 if (go.SpawnTime <= music.CurrentPosition * speedChangeFactor)
  973.                 {
  974.                     notes.Add(go);
  975.                     toDel.Add(go);
  976.                 }
  977.             }
  978.             foreach (GameObject go in toDel)
  979.             {
  980.                 notesToSpawn.Remove(go);
  981.             }
  982.             toDel.Clear();
  983.             toDel = null;
  984.         }
  985.  
  986.         private void CheckCollisions(GameTime gameTime)
  987.         {
  988.             List<GameObject> toDel = new List<GameObject>();
  989.             double seconds = gameTime.TotalGameTime.TotalSeconds;
  990.             foreach (GameObject note in notes)
  991.             {
  992.                 if (player.Intersects(note))
  993.                 {
  994.                     if (!String.IsNullOrEmpty(note.Tag) && (note.OnCollision != null))
  995.                         note.OnCollision.Invoke(player);
  996.  
  997.                     float bonus;
  998.                     bonus = baseScaleBonus * note.Scale;
  999.                     bonus += baseSpeedBonus * note.Speed.Length();
  1000.                     if (note.Variation != null)
  1001.                         bonus *= baseVariationBonus;
  1002.                     if (note.Color == Color.Red)
  1003.                     {
  1004.                         bonus *= baseNegativeBonus;
  1005.                         multiplier = baseNegativeMultiplier;
  1006.                         numberOfCaughtBadNotes++;
  1007.                     }
  1008.                     else
  1009.                     {
  1010.                         multiplier += multiplierIncrement;
  1011.                         numberOfCaughtNotes++;
  1012.                     }
  1013.                     scoreColor = note.Color;
  1014.                     score += (int)bonus;
  1015.                     timedFloatingBonuses.Add(new FloatingText(player.Position,
  1016.                         bonus > 0 ? String.Format("+{0}", (int)bonus) : bonus.ToString("N0"),
  1017.                         note.Color, seconds));
  1018.                     toDel.Add(note);
  1019.                 }
  1020.                 else if ((note.Position.Y > this.graphics.PreferredBackBufferHeight) || (note.Position.Y < 0)
  1021.                     || (note.Position.X > this.graphics.PreferredBackBufferWidth) || (note.Position.X < 0))
  1022.                     toDel.Add(note);
  1023.             }
  1024.             foreach (GameObject note in toDel)
  1025.                 notes.Remove(note);
  1026.             toDel.Clear();
  1027.             toDel = null;
  1028.         }
  1029.  
  1030.         private void UpdateFloatingText(GameTime gameTime)
  1031.         {
  1032.             List<FloatingText> textToDel = new List<FloatingText>();
  1033.             double seconds = gameTime.TotalGameTime.TotalSeconds;
  1034.             foreach (FloatingText txt in timedFloatingBonuses)
  1035.             {
  1036.                 if (seconds - txt.SpawnTime < secondsBeforeTextElapses)
  1037.                 {
  1038.                     txt.Color = new Color(txt.Color.R, txt.Color.G, txt.Color.B,
  1039.                         (byte)((1 - ((seconds - txt.SpawnTime) / secondsBeforeTextElapses)) * 255));
  1040.                     txt.Position -= Vector2.UnitY * 2;
  1041.                 }
  1042.                 else
  1043.                     textToDel.Add(txt);
  1044.             }
  1045.             foreach (FloatingText txt in textToDel)
  1046.                 timedFloatingBonuses.Remove(txt);
  1047.             textToDel.Clear();
  1048.             textToDel = null;
  1049.         }
  1050.  
  1051.         protected override void Update(GameTime gameTime)
  1052.         {
  1053.             if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
  1054.                 this.Exit();
  1055.  
  1056.             switch (currentMode)
  1057.             {
  1058.                 case GameMode.Menu :
  1059.                     ProcessMenuInput();
  1060.                     break;
  1061.                 case GameMode.FileSelection :
  1062.                     ProcessFileSelectionInput();
  1063.                     break;
  1064.                 case GameMode.Processing :
  1065.                     if ((completePercentage == 100f) && (!temp.IsAlive))
  1066.                         StartPlaying();
  1067.                     break;
  1068.                 case GameMode.Playing :
  1069.                     SpawnNotes();
  1070.                     ProcessGameInput(gameTime);
  1071.                     double seconds = gameTime.TotalGameTime.TotalSeconds;
  1072.  
  1073.                     foreach (GameObject note in notes)
  1074.                         note.Update(gameTime);
  1075.                     if (magnetEnabled)
  1076.                     {
  1077.                         foreach(GameObject note in notes)
  1078.                             if (note.Color != Color.Red)
  1079.                             {
  1080.                                 Vector2 tmp = player.Position - note.Position;
  1081.                                 tmp.Normalize();
  1082.                                 note.Speed = tmp * (note.Speed.Length() > 3.0f ? note.Speed.Length() : 5.0f);
  1083.                                 note.Variation = null;
  1084.                             }
  1085.                         if (seconds - magnetStartTime > magnetDuration)
  1086.                             magnetEnabled = false;
  1087.                     }
  1088.  
  1089.                     CheckCollisions(gameTime);
  1090.                     UpdateFloatingText(gameTime);
  1091.  
  1092.                     if ((rnd.NextDouble() < spiralApparitionPercent) && !spiralAppeared)
  1093.                     {
  1094.                         spiral = new GameObject();
  1095.                         spiral.Sprite = haloSpiral;
  1096.                         spiral.Position = new Vector2((float)(this.graphics.PreferredBackBufferWidth / 2 - spiral.Sprite.Width / 2), (float)(this.graphics.PreferredBackBufferHeight / 2 - spiral.Sprite.Height / 2));
  1097.                         spiral.Variation = GameObject.RotationVariation;
  1098.                         spiral.Tag = "spiral";
  1099.                         spiral.OnCollision = SpiralCreationEvent;
  1100.                         notes.Add(spiral);
  1101.                         spiralAppeared = true;
  1102.                         spiralApparitionTime = seconds;
  1103.                     }
  1104.                     if ((spiral != null) && (seconds - spiralApparitionTime > 5))
  1105.                     {
  1106.                         notes.Remove(spiral);
  1107.                         spiral = null;
  1108.                     }
  1109.  
  1110.                     try
  1111.                     {
  1112.                         if (music.CurrentPosition >= music.Duration)
  1113.                         {
  1114.                             music.Stop();
  1115.                             currentMode = GameMode.GameOver;
  1116.                             records.Add(new Record(Path.GetFileNameWithoutExtension(waveFileName),
  1117.                                 DateTime.Now, score, (byte)Properties.Settings.Default.Difficulty,
  1118.                                 numberOfNotes, numberOfCaughtNotes, numberOfBadNotes,
  1119.                                 numberOfCaughtBadNotes, currentWaveMode == WaveMode.Mono ? "Mono" : "Stereo"));
  1120.                             records.Save(recordsFolder + "\\records.dat");
  1121.                         }
  1122.                     }
  1123.                     catch
  1124.                     {
  1125.                         currentMode = GameMode.GameOver;
  1126.                         records.Add(new Record(Path.GetFileNameWithoutExtension(waveFileName),
  1127.                             DateTime.Now, score, (byte)Properties.Settings.Default.Difficulty,
  1128.                             numberOfNotes, numberOfCaughtNotes, numberOfBadNotes,
  1129.                             numberOfCaughtBadNotes, currentWaveMode == WaveMode.Mono ? "Mono" : "Stereo"));
  1130.                         records.Save(recordsFolder + "\\records.dat");
  1131.                     }
  1132.                     break;
  1133.                 case GameMode.GameOver :
  1134.                     ProcessGameOverInput();
  1135.                     break;
  1136.             }
  1137.  
  1138.             base.Update(gameTime);
  1139.         }
  1140.    #endregion
  1141.  
  1142.    #region "Disegno"
  1143.         private static Vector2 vector20 = new Vector2(20, 20);
  1144.  
  1145.         private void DrawMenu()
  1146.         {
  1147.             Color c;
  1148.             Vector2 size;
  1149.             spriteBatch.Draw(logo, new Rectangle((int)(this.graphics.PreferredBackBufferWidth / 2 - logo.Width / 2), 10, logo.Width, logo.Height), Color.White);
  1150.             for (Int32 i = 0; i < menuItems.Length; i++)
  1151.             {
  1152.                 c = Color.White;
  1153.                 if (i == selectedIndex)
  1154.                     c = Color.Yellow;
  1155.                 size = menuItemFont.MeasureString(menuItems[i]);
  1156.                 spriteBatch.DrawString(menuItemFont, menuItems[i], new Vector2((int)(this.graphics.PreferredBackBufferWidth / 2 - size.X/2), 240 + i * 30), c);
  1157.             }
  1158.         }
  1159.  
  1160.         private void DrawFileSelection()
  1161.         {
  1162.             if (wavesList == null)
  1163.                 return;
  1164.             Color c;
  1165.             Int32 filesNumber = (int)((this.graphics.PreferredBackBufferHeight - 40) / 30);
  1166.             float y = 20f;
  1167.             for (Int32 i = (selectedIndex / filesNumber) * filesNumber; i < wavesList.Count; i++)
  1168.             {
  1169.                 if (File.Exists(wavesList[i]))
  1170.                     c = Color.White;
  1171.                 else if (Directory.Exists(wavesList[i]))
  1172.                     c = Color.Green;
  1173.                 else
  1174.                     c = Color.Red;
  1175.                 if (i == selectedIndex)
  1176.                     c = Color.Yellow;
  1177.                 spriteBatch.DrawString(menuItemFont, Path.GetFileNameWithoutExtension(wavesList[i]), new Vector2(20, y), c);
  1178.                 y += 30f;
  1179.                 if (y + 30 > this.graphics.PreferredBackBufferHeight)
  1180.                     break;
  1181.             }
  1182.         }
  1183.  
  1184.         private void DrawCompletePercentage()
  1185.         {
  1186.             spriteBatch.DrawString(menuItemFont, String.Format("Elaborazione in corso: {0:N2}%", completePercentage), vector20, Color.White);
  1187.         }
  1188.  
  1189.         private void DrawGameInterface()
  1190.         {
  1191.             spriteBatch.DrawString(menuItemFont, "Score: " + score.ToString(), vector20, scoreColor);
  1192.             foreach (FloatingText txt in timedFloatingBonuses)
  1193.                 spriteBatch.DrawString(menuItemFont, txt.Text, txt.Position, txt.Color);
  1194.             spriteBatch.DrawString(menuItemFont,
  1195.                 String.Format("Moltiplicatore: {0:N1}  -  Magneti: {1}  -  Colore: {2}", multiplier, availableMagnets, availableAllColors),
  1196.                 new Vector2(20, this.graphics.PreferredBackBufferHeight - 40), Color.White);
  1197.         }
  1198.  
  1199.         private void DrawGameOverInterface()
  1200.         {
  1201.             Vector2 size = bigFont.MeasureString(score.ToString());
  1202.             String notesInfo = String.Format("Note prese: {0} / {1}", numberOfCaughtNotes, numberOfNotes);
  1203.             String badNotesInfo = String.Format("Note prese: {0} / {1}", numberOfCaughtBadNotes, numberOfBadNotes);
  1204.             Color c;
  1205.             spriteBatch.DrawString(bigFont, score.ToString(), new Vector2((int)(this.graphics.PreferredBackBufferWidth / 2 - size.X / 2), 50), scoreColor);
  1206.             size = bigFont.MeasureString(notesInfo);
  1207.             spriteBatch.DrawString(bigFont, notesInfo, new Vector2((int)(this.graphics.PreferredBackBufferWidth / 2 - size.X / 2), 100), Color.White);
  1208.             size = bigFont.MeasureString(badNotesInfo);
  1209.             spriteBatch.DrawString(bigFont, badNotesInfo, new Vector2((int)(this.graphics.PreferredBackBufferWidth / 2 - size.X / 2), 150), Color.Red);
  1210.             for (Int32 i = 0; i < gameOverMenuItems.Length; i++)
  1211.             {
  1212.                 c = Color.White;
  1213.                 if (i == selectedIndex)
  1214.                     c = Color.Yellow;
  1215.                 size = menuItemFont.MeasureString(gameOverMenuItems[i]);
  1216.                 spriteBatch.DrawString(menuItemFont, gameOverMenuItems[i], new Vector2((int)(this.graphics.PreferredBackBufferWidth / 2 - size.X / 2), 250 + i * 30), c);
  1217.             }
  1218.         }
  1219.    #endregion
  1220.  
  1221.         protected override void Draw(GameTime gameTime)
  1222.         {
  1223.             graphics.GraphicsDevice.Clear(Color.Black);
  1224.  
  1225.             spriteBatch.Begin();
  1226.             switch (currentMode)
  1227.             {
  1228.                 case GameMode.Menu :
  1229.                     DrawMenu();
  1230.                     break;
  1231.                 case GameMode.FileSelection :
  1232.                     DrawFileSelection();
  1233.                     break;
  1234.                 case GameMode.Processing :
  1235.                     DrawCompletePercentage();
  1236.                     break;
  1237.                 case GameMode.Playing :
  1238.                     foreach (GameObject go in notes)
  1239.                         go.Draw(spriteBatch);
  1240.                     player.Draw(spriteBatch);
  1241.                     DrawGameInterface();
  1242.                     break;
  1243.                 case GameMode.GameOver :
  1244.                     DrawGameOverInterface();
  1245.                     break;
  1246.             }
  1247.             spriteBatch.End();
  1248.  
  1249.             base.Draw(gameTime);
  1250.         }
  1251.     }
  1252. }