Пример #1
0
        public SQLiteData(SQLiteDataReader data)
        {
            foreach (FieldInfo prop in GetType().GetFields())
            {
                try
                {
                    switch (prop.Name.ToLower())
                    {
                    case "datet":
                        prop.SetValue(this, data[prop.Name.ToLower()].ToString());
                        break;

                    default:
                        prop.SetValue(this, data[prop.Name.ToLower()]);
                        break;
                    }
                }
                catch
                {
                    try
                    {
                        PulsarcLogger.Warning($"Data field in SQLite request could not be set as a {prop.FieldType.Name} : {data[prop.Name.ToLower()]}", LogType.Runtime);
                    }
                    catch
                    {
                        PulsarcLogger.Warning($"Unexpected data field in SQLite request : {prop.Name}", LogType.Runtime);
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Start playing audio
        /// </summary>
        public static void StartLazyPlayer()
        {
            Stop();

            if (songPath == "")
            {
                return;
            }

            // Initialize the song
            try
            {
                song = new AudioTrack(songPath)
                {
                    Rate   = audioRate,
                    Volume = Config.GetInt("Audio", "MusicVolume"),
                };
            }
            catch (AudioEngineException)
            {
                PulsarcLogger.Error(ManagedBass.Bass.LastError.ToString(), LogType.Runtime);
            }

            song.ApplyRate(Config.GetBool("Audio", "RatePitch"));

            song.Play();
            active = true;
        }
Пример #3
0
        /// <summary>
        /// Save this setting into the config.ini file.
        /// </summary>
        /// <param name="category">Category to save under</param>
        /// <param name="key">The key to modify.</param>
        public virtual void Save(string category, string key)
        {
            switch (Type)
            {
            case "float":
                Config.SetFloat(category, key, (float)GetSaveValue());
                break;

            case "int":
                Config.SetInt(category, key, (int)GetSaveValue());
                break;

            case "double":
                Config.SetDouble(category, key, (double)GetSaveValue());
                break;

            case "bool":
                Config.SetBool(category, key, (bool)GetSaveValue());
                break;

            case "string":
                Config.SetString(category, key, (string)GetSaveValue());
                break;

            default:
                PulsarcLogger.Error($"Cannot save type {Type.ToString()} in category {category} for setting {key}", LogType.Runtime);
                break;
            }
        }
Пример #4
0
        /// <summary>
        /// Initializes the current GameplayView with the provided beatmap.
        /// </summary>
        /// <param name="beatmap">The beatmap to play through</param>
        public void Init(Beatmap beatmap)
        {
            try
            {
                if (!beatmap.FullyLoaded)
                {
                    beatmap = BeatmapHelper.Load(beatmap.Path, beatmap.FileName);
                }

                // Reset in case it wasn't properly handled outside
                Reset();

                // Load values gained from config/user settings
                LoadConfig(beatmap);

                // Initialize default variables, parse beatmap
                InitializeVariables(beatmap);

                // Initialize Gameplay variables
                InitializeGameplay(beatmap);

                // Create columns and their hitobjects
                CreateColumns();

                // Sort the hitobjects according to their first appearance for optimizing update/draw
                SortHitObjects();

                if (AutoPlay)
                {
                    LoadAutoPlay();
                }

                // Once everything is loaded, initialize the view
                GetGameplayView().Init();

                // Start audio and gameplay
                StartGameplay();

                // Collect any excess memory to prevent GC from starting soon, avoiding freezes.
                // TODO: disable GC while in gameplay
                GC.Collect();

                Init();
            }
            catch
            {
                // Force quit
                EndGameplay();

                // Give warning
                PulsarcLogger.Warning($"There was an error attempting to load {beatmap.Title}, " +
                                      $"going back to Song Select!");

                // Remove Result Screen
                ScreenManager.RemoveScreen();
            }
        }
Пример #5
0
 /// <summary>
 /// Initializes a setting that can change different options in Pulsarc.
 /// </summary>
 /// <param name="title">Name of the Setting</param>
 /// <param name="more"></param>
 /// <param name="position">Setting's position.</param>
 /// <param name="texture">The texture for the Setting.</param>
 /// <param name="anchor">The anchor position for this Setting.</param>
 /// <param name="baseValue">The value this setting starts with.</param>
 /// <param name="type">The type of variable this setting changes.</param>
 public Setting(string title, string more, Vector2 position, Texture2D texture, Anchor anchor, dynamic baseValue, string type)
     : base(texture, position, anchor: anchor)
 {
     Value = baseValue;
     Type  = type;
     PulsarcLogger.Important($"{type} set for {title}", LogType.Runtime);
     Text  = title;
     Title = new TextDisplayElement(title, new Vector2(position.X - 50, position.Y), anchor: Anchor.CenterRight);
 }
Пример #6
0
        /// <summary>
        /// Converts an Intralism beatmap folder to a Pulsarc-compatible beatmap, and then saves the converted Beatmap to storage.
        /// </summary>
        /// <param name="folder_path">The path to the map-to-be-converted folder</param>
        public void Save(string folder_path)
        {
            Beatmap map = Convert(folder_path).First();

            // If the map is null, or audio is null, stop saving.
            if (map == null || map.Audio == null)
            {
                return;
            }

            string audioPath = $"{folder_path}/{map.Audio}";

            // If the path doesn't exist, stop saving.
            if (!File.Exists(audioPath))
            {
                return;
            }

            int id = 0;
            // The folder name will look like "0 - Unknown - MapTitle - (Mapper)"
            string folderName = string.Join("_", ($"{id} - {map.Artist} - {map.Title} ({map.Mapper})").Split(Path.GetInvalidFileNameChars()));
            string dirName    = $"Songs/{folderName}";

            if (!Directory.Exists(dirName))
            {
                Directory.CreateDirectory(dirName);
            }

            // Copy Audio File
            File.Copy(audioPath, $"{dirName}/{map.Audio}", true);

            // Copy Background Image
            string backgroundPath = $"{folder_path}/{map.Background}";

            // Find if the background exists and copy it.
            if (File.Exists(backgroundPath))
            {
                try
                {
                    File.Copy(backgroundPath, $"{dirName}/{map.Background}", true);
                }
                catch
                {
                    PulsarcLogger.Debug("Converting the background failed! Converting wtihout background.", LogType.Runtime);
                }
            }
            else
            {
                map.Background = "";
            }


            // The file name will look like "Unknown - MapTitle [Converted] (Mapper).psc"
            string difficultyFileName = string.Join("_", ($"{map.Artist} - {map.Title} [{map.Version}] ({map.Mapper})").Split(Path.GetInvalidFileNameChars()));

            BeatmapHelper.Save(map, $"{dirName}/{difficultyFileName}.psc");
        }
Пример #7
0
 /// <summary>
 /// Write a property to file
 /// </summary>
 /// <param name="file"></param>
 /// <param name="beatmap"></param>
 /// <param name="property"></param>
 static private void WriteProperty(StreamWriter file, Beatmap beatmap, string property)
 {
     try
     {
         // Use reflection to write any property. The property needs to implement ToString()
         file.WriteLine(property + ": " + beatmap.GetType().GetProperty(property).GetValue(beatmap, null));
     }
     catch
     {
         PulsarcLogger.Error($"Trying to write invalid property {property}", LogType.Runtime);
     }
 }
Пример #8
0
        /// <summary>
        /// Load a skin from the folder name provided.
        /// </summary>
        /// <param name="name">The folder name of the skin to be loaded.</param>
        public static void LoadSkin(string name)
        {
            Assets  = new Dictionary <string, Texture2D>();
            Configs = new Dictionary <String, IniData>();
            Judges  = new Dictionary <int, Texture2D>();
            Sounds  = new Dictionary <string, AudioSample>();
            Loaded  = false;

            string skinFolder = $"Skins/{name}/";

            if (Directory.Exists(skinFolder))
            {
                // Load configs
                LoadConfigs(skinFolder);

                // Load gameplay assets
                LoadSkinTexture($"{skinFolder}Gameplay/", "arcs");
                LoadSkinTexture($"{skinFolder}Gameplay/", "crosshair");
                LoadSkinTexture($"{skinFolder}Gameplay/", "map_timer");

                // Load cursor asset
                LoadSkinTexture($"{skinFolder}UI/", "cursor");

                // Load Main Menu assets
                LoadMainMenu(skinFolder);

                // Load Result Screen assets (not including Grades)
                LoadResultScreen(skinFolder);

                // Load Song Select assets
                LoadSongSelect(skinFolder);

                // Load settings assets
                LoadSettings(skinFolder);

                // Load Grade assets
                LoadGrades(skinFolder);

                // Load judge assets
                LoadJudges(skinFolder);

                // Load sounds
                LoadSounds(skinFolder);

                Loaded = true;
            }
            else
            {
                PulsarcLogger.Error($"Could not find the skin {name}", LogType.Network);
            }
        }
Пример #9
0
        public static Texture2D LoadFileTexture(string path)
        {
            Texture2D texture;

            try
            {
                texture = Texture2D.FromStream(Pulsarc.Graphics.GraphicsDevice, File.Open(path, FileMode.Open));
            }
            catch
            {
                PulsarcLogger.Error($"Failed to load {path}", LogType.Runtime);
                texture = Skin.DefaultTexture;
            }

            return(texture);
        }
Пример #10
0
        public override void Draw()
        {
            if (caught)
            {
                return;
            }

            try
            {
                Pulsarc.SpriteBatch.DrawString(font, Text, processedPosition, Color, 0, origin, fontScale, SpriteEffects.None, 0);
            }
            catch
            {
                PulsarcLogger.Error($"Could not write {Text}, Aborting Draw() calls for this TextDisplayElement until Update() has been called.", LogType.Runtime);
                caught = true; // Don't need to spam the console with Errors
            }
        }
Пример #11
0
        /// <summary>
        /// Initialize most static objects and dependencies
        /// </summary>
        protected override void Initialize()
        {
            base.Initialize();

            // Copy, if needed, the required assemblies (BASS) for 32 or 64bit CPUs
            NativeAssemblies.Copy();

            // Initialize the logging tool for troubleshooting
            PulsarcLogger.Initialize();

            // Initialize Discord Rich Presence
            PulsarcDiscord.Initialize();

            // Set the default culture (Font formatting Locals) for this thread
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

            // Start the thread listening for user input
            InputManager.StartThread();

            // Start our time and frame-time tracker
            PulsarcTime.Start();

            // Initialize FPS
            fpsDisplay = new FPS(Vector2.Zero);

            // Initialize the game camera
            gameCamera = new Camera(Graphics.GraphicsDevice.Viewport, (int)GetDimensions().X, (int)GetDimensions().Y, 1)
            {
                Pos = new Vector2(GetDimensions().X / 2, GetDimensions().Y / 2)
            };

            // Start the song selection in the background to have music when entering the game
            SongScreen = new SongSelection();
            SongScreen.Init();

            // Create and display the default game screen
            // (Currently Main menu. In the future can implement an intro)
            Menu firstScreen = new Menu();

            ScreenManager.AddScreen(firstScreen);

            cursor = new Cursor();

            IsReadyToUpdate = true;
        }
Пример #12
0
 /// <summary>
 /// Attempts to return the texture found using the folder path and file asset name provided.
 /// </summary>
 /// <param name="path">The folder loaction of the texture.</param>
 /// <param name="asset">The name of the file to load.</param>
 /// <returns>A texture using the image file found, or an uninitialized "Default Texture" if the asset can't be loaded.</returns>
 private static Texture2D LoadTexture(string path, string asset)
 {
     // Try opening as a .png
     try
     {
         return(Texture2D.FromStream(Pulsarc.Graphics.GraphicsDevice, File.Open($"{path}/{asset}.png", FileMode.Open)));
     }
     catch
     {
         // Try opening as a .jpg
         try
         {
             return(Texture2D.FromStream(Pulsarc.Graphics.GraphicsDevice, File.Open($"{path}/{asset}.jpg", FileMode.Open)));
         }
         // Don't load, throw a console error, and return default texture.
         catch
         {
             PulsarcLogger.Warning($"Failed to load {asset} in {path}, make sure it is a .png or .jpg file!", LogType.Runtime);
             return(DefaultTexture);
         }
     }
 }
Пример #13
0
        /// <summary>
        /// Change the the audio rate to the one defined
        /// in the config.
        /// </summary>
        public static void UpdateRate()
        {
            if (active)
            {
                // Save the position and audio path.
                double time  = GetTime();
                string audio = songPath;
                Stop();

                // Find the audio rate.
                songPath  = audio;
                audioRate = Config.GetFloat("Gameplay", "SongRate");
                StartLazyPlayer();

                // Play the rate-changed song at the time saved earlier.
                if (time != 0)
                {
                    DeltaTime((long)time);
                }

                PulsarcLogger.Important($"Now Playing: {songPath} at {audioRate} rate", LogType.Runtime);
            }
        }
Пример #14
0
        /// <summary>
        /// Load a single Beatmap.
        /// </summary>
        /// <param name="path">The path to the beatmap folder.</param>
        /// <param name="fileName">The fileName of the .psc file.</param>
        static public Beatmap Load(string path, string fileName)
        {
            Beatmap parsed = new Beatmap();

            parsed.Path     = path;
            parsed.FileName = fileName;

            var state = "";

            var lines = File.ReadLines($"{path}/{fileName}");

            foreach (var line in lines)
            {
                if (line.Length > 0)
                {
                    // Information like Metadata are in the form 'Type: Data'
                    Queue <string> lineParts = new Queue <string>(line.Split(':'));

                    // If we recognize this form, it's an attribute.
                    // Otherwise, it is a more complex data form, like an event
                    if (lineParts.Count > 1)
                    {
                        var type      = lineParts.Dequeue();
                        var rightPart = string.Concat(lineParts.ToArray()).Trim();

                        // Use reflection to set the Beatmap's attributes
                        switch (type)
                        {
                        case "FormatVersion":
                        case "Title":
                        case "Artist":
                        case "Mapper":
                        case "Version":
                        case "MapOffset":
                            try
                            {
                                parsed.GetType().GetProperty(type).SetValue(parsed, rightPart);
                            }
                            catch
                            {
                                PulsarcLogger.Error($"Unknown beatmap field : {type}", LogType.Runtime);
                            }
                            break;

                        case "Audio":
                            try
                            {
                                parsed.GetType().GetProperty(type).SetValue(parsed, rightPart);
                            }
                            catch
                            {
                                PulsarcLogger.Error($"Unknown beatmap field : {type}", LogType.Runtime);
                            }
                            break;

                        case "Background":
                        {
                            try
                            {
                                parsed.GetType().GetProperty(type).SetValue(parsed, rightPart);
                            }
                            catch
                            {
                                PulsarcLogger.Error($"Unknown beatmap field : {type}", LogType.Runtime);
                            }
                            break;
                        }

                        case "PreviewTime":
                        case "KeyCount":
                            try
                            {
                                parsed.GetType().GetProperty(type).SetValue(parsed, int.Parse(rightPart));
                            }
                            catch
                            {
                                PulsarcLogger.Error($"Unknown beatmap field : {type}", LogType.Runtime);
                            }
                            break;

                        case "Difficulty":
                            try
                            {
                                parsed.GetType().GetProperty(type).SetValue(parsed, Double.Parse(rightPart, CultureInfo.InvariantCulture));
                            }
                            catch
                            {
                                PulsarcLogger.Error($"Unknown beatmap field : {type}", LogType.Runtime);
                            }
                            break;

                        case "Events":
                        case "TimingPoints":
                        case "SpeedVariations":
                        case "Arcs":
                            state = type;
                            break;

                        default:
                            // Should probably ingore this really, like why would we need to know that?
                            //PulsarcLogger.Error($"Unknown beatmap field : {type}", LogType.Runtime);
                            break;
                        }
                    }
                    else
                    {
                        // Each event is comma separated and can have any amount of values.
                        var eventParts = line.Split(',');

                        // Handling depends on the data type (or the current reading state)
                        switch (state)
                        {
                        case "Events":
                            try
                            {
                                int type = int.Parse(eventParts[(int)EventIndex.Type]);

                                Event evnt = MakeEvent(line, (EventType)type);
                                if (evnt != null)
                                {
                                    parsed.Events.Add(evnt);
                                }
                            }
                            catch
                            {
                                PulsarcLogger.Error($"Invalid Event : {line}", LogType.Runtime);
                            }
                            break;

                        case "TimingPoints":
                            try
                            {
                                parsed.TimingPoints.Add(new TimingPoint(Convert.ToInt32(eventParts[0]), Convert.ToInt32(eventParts[1])));
                            }
                            catch
                            {
                                PulsarcLogger.Error($"Invalid TimingPoint : {line}", LogType.Runtime);
                            }
                            break;

                        case "Arcs":
                            try
                            {
                                parsed.Arcs.Add(new Arc(Convert.ToInt32(eventParts[0]), Convert.ToInt32(eventParts[1], 2)));
                            }
                            catch
                            {
                                PulsarcLogger.Error($"Invalid Arc : {line}", LogType.Runtime);
                            }
                            break;

                        default:
                            PulsarcLogger.Error($"Invalid state : {line}", LogType.Runtime);
                            break;
                        }
                    }
                }
            }

            // If no difficulty has been provided in the game file, process it now.
            if (parsed.Difficulty == 0)
            {
                parsed.Difficulty = DifficultyCalculation.GetDifficulty(parsed);
            }

            parsed.FullyLoaded = true;

            return(parsed);
        }
Пример #15
0
        private async void ConvertMaps()
        {
            // Temporary measure for converting intralism or osu!mania beatmaps
            // TODO Make a Converter UI
            if (!converting && !GameplayEngine.Active &&
                Keyboard.GetState().IsKeyDown(Config.Bindings["Convert"]) &&
                ScreenManager.Screens.Peek().GetType().Name == "SongSelection")
            {
                converting = true;
                IBeatmapConverter converter;

                Config.Reload();
                string convertFrom = Config.Get["Converting"]["Game"];
                string toConvert   = Config.Get["Converting"]["Path"];

                // What extension to check for
                string extension;

                switch (convertFrom.ToLower())
                {
                case "mania":
                    converter = new ManiaToPulsarc();
                    extension = "*.osu";
                    break;

                default:
                    converter = new IntralismToPulsarc();
                    extension = "config.txt";
                    break;
                }

                // Get all subfolder names
                string[] directories = Directory.GetDirectories(toConvert);

                // If there is no maps in this folder, and the number of sub-folders is 2 or more,
                // do a Batch Convert
                if (Directory.GetFiles(toConvert, extension).Length == 0 && directories.Length >= 2)
                {
                    for (int i = 0; i < directories.Length; i++)
                    {
                        try
                        {
                            converter.Save(directories[i]);
                        }
                        catch
                        {
                            PulsarcLogger.Warning($"Couldn't convert {directories[i]}");
                        }
                    }
                }
                // Otherwise convert one map
                else
                {
                    try
                    {
                        converter.Save(toConvert);
                    }
                    catch
                    {
                        PulsarcLogger.Warning($"Couldn't convert {toConvert}");
                    }
                }

                ((SongSelection)ScreenManager.Screens.Peek()).RescanBeatmaps();
            }
            else if (converting && Keyboard.GetState().IsKeyUp(Config.Bindings["Convert"]))
            {
                converting = false;
            }
        }