예제 #1
0
        public static void LoadPreview(CSong song, float start = -1f)
        {
            if (song == null)
            {
                throw new ArgumentNullException("song");
            }

            if (!IsPlayingPreview)
            {
                Pause();
                CSound.SetGlobalVolume(CConfig.PreviewMusicVolume);
            }

            bool songChanged = _CurPlayer.SongID != song.ID;

            _PreviewPlayer.Load(song);


            //Change song position only if song is changed or near to end
            if (songChanged || _CurPlayer.Position + 30 < _CurPlayer.Length)
            {
                _PreviewStartHelperTask = new Task(() =>
                {
                    float length = _PreviewPlayer.Length;
                    if (length < 1)
                    {
                        length = 30; // If length is unknow or invalid assume a length of 30s
                    }
                    if (start < 0)
                    {
                        start = (song.Preview.Source == EDataSource.None) ? length / 4f : song.Preview.StartTime;
                    }
                    if (start > length - 5f)
                    {
                        start = Math.Max(0f, Math.Min(length / 4f, length - 5f));
                    }
                    if (start >= 0.5f)
                    {
                        start -= 0.5f;
                    }

                    _PreviewPlayer.Position = start;
                    Play();
                });
                _CurPlayer = _PreviewPlayer;
            }
            else
            {
                _PreviewStartHelperTask.Dispose();
                _PreviewStartHelperTask = null;
                _PreviewPlayer.Position = _CurPlayer.Position;
                _CurPlayer = _PreviewPlayer;
                Play();
            }
        }
예제 #2
0
        private int _GetDataBaseSongID(int songID, SQLiteCommand command)
        {
            CSong song = CSongs.GetSong(songID);

            if (song == null)
            {
                return(-1);
            }

            return(_GetDataBaseSongID(song.Artist, song.Title, 0, command));
        }
예제 #3
0
파일: CSongs.cs 프로젝트: zhaozw/Vocaluxe
        public static void LoadSongs()
        {
            CLog.StartBenchmark(1, "Load Songs");
            _SongsLoaded = false;
            _Songs.Clear();

            CLog.StartBenchmark(2, "List Songs");
            List <string> files = new List <string>();

            foreach (string p in CConfig.SongFolder)
            {
                string path = p;
                files.AddRange(Helper.ListFiles(path, "*.txt", true, true));
                files.AddRange(Helper.ListFiles(path, "*.txd", true, true));
            }
            CLog.StopBenchmark(2, "List Songs");

            CLog.StartBenchmark(2, "Read TXTs");
            foreach (string file in files)
            {
                CSong Song = new CSong();
                if (Song.ReadTXTSong(file))
                {
                    Song.ID = _Songs.Count;
                    _Songs.Add(Song);
                }
            }
            CLog.StopBenchmark(2, "Read TXTs");

            CLog.StartBenchmark(2, "Sort Songs");
            Sort(CConfig.SongSorting);
            CLog.StopBenchmark(2, "Sort Songs");
            Category     = -1;
            _SongsLoaded = true;

            if (CConfig.Renderer != ERenderer.TR_CONFIG_SOFTWARE && CConfig.CoverLoading == ECoverLoading.TR_CONFIG_COVERLOADING_ATSTART)
            {
                CLog.StartBenchmark(2, "Load Cover");
                for (int i = 0; i < _Songs.Count; i++)
                {
                    CSong song = _Songs[i];

                    song.ReadNotes();
                    STexture texture = song.CoverTextureSmall;
                    song.CoverTextureBig = texture;
                    _CoverLoadIndex++;
                }

                _CoverLoaded = true;
                CDataBase.CommitCovers();
                CLog.StopBenchmark(2, "Load Cover");
            }
            CLog.StopBenchmark(1, "Load Songs ");
        }
예제 #4
0
        public void Load(CSong song, float position = 0f, bool autoplay = false)
        {
            if (song == null)
            {
                throw new ArgumentNullException("song");
            }

            Load(song.GetMP3(), position, autoplay);
            _Song = song;
            _LoadVideo();
        }
예제 #5
0
        private void _PlaySong(int nr)
        {
            _PreviewNrInternal = -1;

            CSong song = CBase.Songs.GetVisibleSong(nr);

            if (song == null)
            {
                return;
            }

            CBase.BackgroundMusic.LoadPreview(song, song.Preview.StartTime);
        }
예제 #6
0
        private void _UpdateList(int offset, bool force = false)
        {
            bool isInCategory    = CBase.Songs.IsInCategory();
            int  itemCount       = isInCategory ? CBase.Songs.GetNumSongsVisible() : CBase.Songs.GetNumCategories();
            int  totalSongNumber = CBase.Songs.GetNumSongs();

            offset = offset.Clamp(0, itemCount - _ListLength, true);

            if (offset == _Offset && !force)
            {
                return;
            }

            for (int i = 0; i < _Tiles.Count; i++)
            {
                if (i + offset < itemCount)
                {
                    _Tiles[i].Color = new SColorF(1f, 1f, 1f, 1f);
                    if (isInCategory)
                    {
                        CSong currentSong = CBase.Songs.GetVisibleSong(i + offset);
                        _Tiles[i].Texture = currentSong.CoverTextureSmall;

                        if (CBase.Config.GetSongSorting() == ESongSorting.TR_CONFIG_TITLE_LETTER)
                        {
                            _Texts[i].Text = currentSong.Title + " - " + currentSong.Artist;
                        }
                        else
                        {
                            _Texts[i].Text = currentSong.Artist + " - " + currentSong.Title;
                        }
                    }
                    else
                    {
                        CCategory currentCat = CBase.Songs.GetCategory(i + offset);
                        _Tiles[i].Texture = currentCat.CoverTextureSmall;
                        int    num         = currentCat.GetNumSongsNotSung();
                        String songOrSongs = (num == 1) ? "TR_SCREENSONG_NUMSONG" : "TR_SCREENSONG_NUMSONGS";
                        _Texts[i].Text = currentCat.Name + " " + CBase.Language.Translate(songOrSongs).Replace("%v", num.ToString());
                    }
                }
                else
                {
                    _Tiles[i].Color.A = 0;
                    _Texts[i].Text    = "";
                }
            }
            _Offset = offset;
        }
예제 #7
0
파일: CSongs.cs 프로젝트: zhaozw/Vocaluxe
        private static void _LoadCover()
        {
            for (int i = 0; i < _Songs.Count; i++)
            {
                CSong song = _Songs[i];

                song.ReadNotes();
                STexture texture = song.CoverTextureSmall;
                song.CoverTextureBig = texture;
                _CoverLoadIndex++;
            }

            _CoverLoaded = true;
            CDataBase.CommitCovers();
        }
예제 #8
0
파일: CSongs.cs 프로젝트: zhaozw/Vocaluxe
        public static int GetNextSongWithoutCover(ref CSong Song)
        {
            if (!SongsLoaded)
            {
                return(-1);
            }

            if (_Songs.Count > _CoverLoadIndex + 1)
            {
                _CoverLoadIndex++;
                Song = _Songs[_CoverLoadIndex];
                return(_CoverLoadIndex);
            }

            return(-2);
        }
예제 #9
0
        protected override CSong _PrepareSong(CSong song)
        {
            if (!song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_SHORTSONG))
            {
                return(null);
            }
            var newSong = new CSong(song)
            {
                Finish = CGame.GetTimeFromBeats(song.ShortEnd.EndBeat, song.BPM) + CSettings.DefaultMedleyFadeOutTime + song.Gap
            };

            // set lines to short mode
            newSong.Notes.SetMedley(0, song.ShortEnd.EndBeat);

            return(newSong);
        }
예제 #10
0
파일: CSongs.cs 프로젝트: zhaozw/Vocaluxe
        public static int GetRandomSong()
        {
            if (_SongsForRandom.Count == 0)
            {
                UpdateRandomSongList();
            }

            if (_SongsForRandom.Count == 0)
            {
                return(-1);
            }

            CSong song = _SongsForRandom[CGame.Rand.Next(0, _SongsForRandom.Count - 1)];

            _SongsForRandom.Remove(song);
            return(GetVisibleSongNumber(song.ID));
        }
예제 #11
0
        private static float[] _GetNoteTimeBeforeBeat(int beat)
        {
            CSong song      = GetSong();
            int   startBeat = (int)Math.Floor(beat - GetBeatFromTime(CSettings.PauseResetTime, song.BPM, 0f));
            int   lastStart = 0;
            int   nextStart = 0;

            foreach (CVoice voice in song.Notes.Voices)
            {
                int lastEnd       = 0;
                int voiceStart    = 0;
                int nextStartNote = 0;
                foreach (CSongLine line in voice.Lines)
                {
                    foreach (CSongNote note in line.Notes)
                    {
                        if (note.StartBeat > startBeat)
                        {
                            nextStartNote = note.StartBeat;
                            break;
                        }
                        voiceStart = note.StartBeat;
                        lastEnd    = note.EndBeat;
                    }
                    if (nextStartNote > 0)
                    {
                        break;
                    }
                }
                if (nextStartNote - beat > CSettings.PauseResetTime)
                {
                    lastStart = beat;
                }
                else if (nextStartNote - lastEnd > CSettings.PauseResetTime)
                {
                    lastStart = nextStartNote - (int)Math.Floor(GetBeatFromTime(CSettings.PauseResetTime, song.BPM, 0f));
                }
                if (voiceStart > lastStart)
                {
                    lastStart = voiceStart;
                    nextStart = nextStartNote;
                }
            }

            return(new float[] { GetTimeFromBeats(lastStart, GetSong().BPM), nextStart });
        }
예제 #12
0
 public void StartNextRound(SPlayer[] players)
 {
     if (IsFinished())
     {
         return;
     }
     if (_CurrentRound > -1)
     {
         _Points.SetPoints(
             _CurrentRound,
             _SongQueue[_CurrentRound].SongID,
             players,
             _SongQueue[_CurrentRound].GameMode);
     }
     _CurrentRound++;
     _CurrentSong = IsFinished() ? null : CGameModes.Get(GetCurrentGameMode()).GetSong(_SongQueue[_CurrentRound].SongID);
 }
예제 #13
0
        private void UpdateRatings()
        {
            CSong song = CGame.GetSong(_Round);

            if (song == null)
            {
                return;
            }

            Texts[htTexts(TextSong)].Text = song.Artist + " - " + song.Title;
            if (_Points.NumRounds > 1)
            {
                Texts[htTexts(TextSong)].Text += " (" + _Round + "/" + _Points.NumRounds + ")";
            }

            SPlayer[] player = new SPlayer[CGame.NumPlayer];
            player = _Points.GetPlayer(_Round - 1, CGame.NumPlayer);
            for (int p = 0; p < player.Length; p++)
            {
                Texts[htTexts(TextNames[p, CGame.NumPlayer - 1])].Text      = player[p].Name;
                Texts[htTexts(TextScores[p, CGame.NumPlayer - 1])].Text     = ((int)Math.Round(player[p].Points)).ToString("0000") + " " + CLanguage.Translate("TR_SCREENSCORE_POINTS");
                Texts[htTexts(TextRatings[p, CGame.NumPlayer - 1])].Text    = CLanguage.Translate("TR_SCREENSCORE_RATING") + ": " + CLanguage.Translate(GetRating((int)Math.Round(player[p].Points)));
                Texts[htTexts(TextDifficulty[p, CGame.NumPlayer - 1])].Text = CLanguage.Translate("TR_SCREENSCORE_GAMEDIFFICULTY") + ": " + CLanguage.Translate(player[p].Difficulty.ToString());
                StaticPointsBarDrawnPoints[p] = 0.0;
                Statics[htStatics(StaticPointsBar[p, CGame.NumPlayer - 1])].Rect.H = 0;
                Statics[htStatics(StaticPointsBar[p, CGame.NumPlayer - 1])].Rect.Y = Statics[htStatics(StaticPointsBarBG[p, CGame.NumPlayer - 1])].Rect.H + Statics[htStatics(StaticPointsBarBG[p, CGame.NumPlayer - 1])].Rect.Y - Statics[htStatics(StaticPointsBar[p, CGame.NumPlayer - 1])].Rect.H;
                if (player[p].ProfileID >= 0 && player[p].ProfileID < CProfiles.NumProfiles)
                {
                    Statics[htStatics(StaticAvatar[p, CGame.NumPlayer - 1])].Texture = CProfiles.Profiles[player[p].ProfileID].Avatar.Texture;
                }
            }

            if (CConfig.ScoreAnimationTime < 1)
            {
                for (int p = 0; p < CGame.NumPlayer; p++)
                {
                    Statics[htStatics(StaticPointsBar[p, CGame.NumPlayer - 1])].Rect.H = ((float)player[p].Points) * (Statics[htStatics(StaticPointsBarBG[p, CGame.NumPlayer - 1])].Rect.H / 10000);
                    Statics[htStatics(StaticPointsBar[p, CGame.NumPlayer - 1])].Rect.Y = Statics[htStatics(StaticPointsBarBG[p, CGame.NumPlayer - 1])].Rect.H + Statics[htStatics(StaticPointsBarBG[p, CGame.NumPlayer - 1])].Rect.Y - Statics[htStatics(StaticPointsBar[p, CGame.NumPlayer - 1])].Rect.H;
                    StaticPointsBarDrawnPoints[p] = player[p].Points;
                }
            }

            timer = new Stopwatch();
            timer.Start();
        }
예제 #14
0
        private void LoadScores()
        {
            CPoints points = CGame.GetPoints();

            if (points == null)
            {
                return;
            }

            _Pos = 0;
            for (int round = 0; round < points.NumRounds; round++)
            {
                SPlayer player = points.GetPlayer(round, CGame.NumPlayer)[0];
                CDataBase.LoadScore(ref _Scores, player);

                if (round == _Round)
                {
                    _IsDuet = false;

                    CSong song = CSongs.GetSong(player.SongID);
                    Texts[htTexts(TextSongName)].Text = song.Artist + " - " + song.Title;

                    switch (CGame.GameMode)
                    {
                    case EGameMode.Normal:
                        Texts[htTexts(TextSongMode)].Text = "TR_GAMEMODE_NORMAL";
                        break;

                    case EGameMode.Medley:
                        Texts[htTexts(TextSongMode)].Text = "TR_GAMEMODE_MEDLEY";
                        break;

                    case EGameMode.Duet:
                        Texts[htTexts(TextSongMode)].Text = "TR_GAMEMODE_DUET";
                        _IsDuet = true;
                        break;

                    default:
                        Texts[htTexts(TextSongMode)].Text = "TR_GAMEMODE_NORMAL";
                        break;
                    }
                }
            }
        }
예제 #15
0
        private void _UpdateRound()
        {
            _IsDuet = false;
            CPoints points = CGame.GetPoints();
            CSong   song   = CGame.GetSong(_Round);

            if (song == null)
            {
                return;
            }

            _Texts[_TextSongName].Text = song.Artist + " - " + song.Title;
            if (points.NumRounds > 1)
            {
                _Texts[_TextSongName].Text += " (" + (_Round + 1) + "/" + points.NumRounds + ")";
            }

            switch (CGame.GetGameMode(_Round))
            {
            case EGameMode.TR_GAMEMODE_NORMAL:
                _Texts[_TextSongMode].Text = "TR_GAMEMODE_NORMAL";
                break;

            case EGameMode.TR_GAMEMODE_MEDLEY:
                _Texts[_TextSongMode].Text = "TR_GAMEMODE_MEDLEY";
                break;

            case EGameMode.TR_GAMEMODE_DUET:
                _Texts[_TextSongMode].Text = "TR_GAMEMODE_DUET";
                _IsDuet = true;
                break;

            case EGameMode.TR_GAMEMODE_SHORTSONG:
                _Texts[_TextSongMode].Text = "TR_GAMEMODE_SHORTSONG";
                break;

            default:
                _Texts[_TextSongMode].Text = "TR_GAMEMODE_NORMAL";
                break;
            }

            _Pos = 0;
        }
예제 #16
0
        private void _SavePlayedSongs()
        {
            for (int round = 0; round < _Points.NumRounds; round++)
            {
                SPlayer[] players = _Points.GetPlayer(round, CGame.NumPlayers);

                for (int p = 0; p < players.Length; p++)
                {
                    if (players[p].Points > CSettings.MinScoreForDB && players[p].SongFinished)
                    {
                        CSong song = CSongs.GetSong(players[p].SongID);
                        CDataBase.IncreaseSongCounter(song.DataBaseSongID);
                        song.NumPlayed++;
                        song.NumPlayedSession++;
                        break;
                    }
                }
            }
        }
예제 #17
0
        private void UpdateRound()
        {
            _IsDuet = false;
            CPoints points = CGame.GetPoints();
            SPlayer player = points.GetPlayer(_Round, CGame.NumPlayer)[0];
            CSong   song   = CGame.GetSong(_Round + 1);

            if (song == null)
            {
                return;
            }

            Texts[htTexts(TextSongName)].Text = song.Artist + " - " + song.Title;
            if (points.NumRounds > 1)
            {
                Texts[htTexts(TextSongName)].Text += " (" + (_Round + 1) + "/" + points.NumRounds + ")";
            }

            switch (CGame.GetGameMode(_Round))
            {
            case EGameMode.TR_GAMEMODE_NORMAL:
                Texts[htTexts(TextSongMode)].Text = "TR_GAMEMODE_NORMAL";
                break;

            case EGameMode.TR_GAMEMODE_MEDLEY:
                Texts[htTexts(TextSongMode)].Text = "TR_GAMEMODE_MEDLEY";
                break;

            case EGameMode.TR_GAMEMODE_DUET:
                Texts[htTexts(TextSongMode)].Text = "TR_GAMEMODE_DUET";
                _IsDuet = true;
                break;

            case EGameMode.TR_GAMEMODE_SHORTSONG:
                Texts[htTexts(TextSongMode)].Text = "TR_GAMEMODE_SHORTSONG";
                break;

            default:
                Texts[htTexts(TextSongMode)].Text = "TR_GAMEMODE_NORMAL";
                break;
            }
        }
예제 #18
0
        private void _PopulateVoiceSelection()
        {
            CSong firstSong = CGame.GetSong(0);

            for (int s = 0; s < CConfig.GetNumScreens(); s++)
            {
                for (int p = 0; p < CSettings.MaxScreenPlayer; p++)
                {
                    if (CGame.GetNumSongs() == 1 && firstSong.IsDuet)
                    {
                        _SelectSlides[_SelectSlideDuetPlayer[s, p]].Clear();

                        for (int j = 0; j < firstSong.Notes.VoiceCount; j++)
                        {
                            _SelectSlides[_SelectSlideDuetPlayer[s, p]].AddValue(firstSong.Notes.VoiceNames[j]);
                        }
                    }
                    else
                    {
                        _SelectSlides[_SelectSlideDuetPlayer[s, p]].Visible = false;
                    }
                }
            }

            /*for (int i = 0; i < (CConfig.GetNumScreens() * CSettings.MaxScreenPlayer); i++)
             * {
             *  if (CGame.GetNumSongs() == 1 && firstSong.IsDuet)
             *  {
             *      _SelectSlides[_PlayerSelectSlideDuet[i]].Clear();
             *      _SelectSlides[_PlayerSelectSlideDuet[i]].Visible = i + 1 <= CGame.NumPlayers;
             *
             *      for (int j = 0; j < firstSong.Notes.VoiceCount; j++)
             *          _SelectSlides[_PlayerSelectSlideDuet[i]].AddValue(firstSong.Notes.VoiceNames[j]);
             *      _SelectSlides[_PlayerSelectSlideDuet[i]].Selection = i % 2;
             *  }
             *  else
             *      _SelectSlides[_PlayerSelectSlideDuet[i]].Visible = false;
             * }*/
        }
예제 #19
0
        private void _LoadProfiles()
        {
            _NameSelections[_NameSelection].UpdateList();

            _UpdateSlides();
            _UpdatePlayerNumber();
            _CheckMics();
            _CheckPlayers();

            CSong firstSong = CGame.GetSong(0);

            for (int i = 0; i < CSettings.MaxNumPlayer; i++)
            {
                _NameSelections[_NameSelection].UseProfile(CGame.Players[i].ProfileID);
                _Statics[_StaticPlayerAvatar[i]].Texture = CProfiles.IsProfileIDValid(CGame.Players[i].ProfileID) ?
                                                           CProfiles.GetAvatarTextureFromProfile(CGame.Players[i].ProfileID) :
                                                           _OriginalPlayerAvatarTextures[i];
                _Texts[_TextPlayer[i]].Text = CProfiles.GetPlayerName(CGame.Players[i].ProfileID, i + 1);
                if (CGame.GetNumSongs() == 1 && firstSong.IsDuet)
                {
                    _SelectSlides[_SelectSlideDuetPlayer[i]].Clear();
                    _SelectSlides[_SelectSlideDuetPlayer[i]].Visible = i + 1 <= CGame.NumPlayers;

                    for (int j = 0; j < firstSong.Notes.VoiceCount; j++)
                    {
                        _SelectSlides[_SelectSlideDuetPlayer[i]].AddValue(firstSong.Notes.VoiceNames[j]);
                    }
                    _SelectSlides[_SelectSlideDuetPlayer[i]].Selection = i % 2;
                }
                else
                {
                    _SelectSlides[_SelectSlideDuetPlayer[i]].Visible = false;
                }
            }
            _NameSelections[_NameSelection].UpdateList();
            _ProfilesChanged = false;
            _AvatarsChanged  = false;
        }
예제 #20
0
        protected override CSong _PrepareSong(CSong song)
        {
            if (!song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_MEDLEY))
            {
                return(null);
            }
            var newSong = new CSong(song)
            {
                Start = CGame.GetTimeFromBeats(song.Medley.StartBeat, song.BPM) - song.Medley.FadeInTime + song.Gap
            };

            if (newSong.Start < 0f)
            {
                newSong.Start = 0f;
            }

            newSong.Finish = CGame.GetTimeFromBeats(song.Medley.EndBeat, song.BPM) + song.Medley.FadeOutTime + song.Gap;

            // set lines to medley mode
            newSong.Notes.SetMedley(song.Medley.StartBeat, song.Medley.EndBeat);

            return(newSong);
        }
예제 #21
0
        private static void _LoadCovers()
        {
            CLog.StartBenchmark("Load Covers");
            int            songCount = _Songs.Count;
            AutoResetEvent ev        = new AutoResetEvent(songCount == 0);

            NumSongsWithCoverLoaded = 0;
            foreach (CSong song in _Songs)
            {
                CSong tmp = song;
                Task.Factory.StartNew(() =>
                {
                    tmp.LoadSmallCover();
                    if (Interlocked.Increment(ref _NumSongsWithCoverLoaded) >= songCount)
                    {
                        ev.Set();
                    }
                });
            }
            ev.WaitOne();
            _CoverLoaded = true;
            CDataBase.CommitCovers();
            CLog.StopBenchmark("Load Covers");
        }
예제 #22
0
        private void _UpdatePreview()
        {
            //First hide everything so we just have to set what we actually want
            _CoverBig.Texture       = _CoverBigBGTexture;
            _Artist.Text            = String.Empty;
            _Title.Text             = String.Empty;
            _SongLength.Text        = String.Empty;
            _SongYear.Text          = String.Empty;
            _DuetIcon.Visible       = false;
            _VideoIcon.Visible      = false;
            _MedleyCalcIcon.Visible = false;
            _MedleyTagIcon.Visible  = false;
            _Length = -1f;

            //Check if nothing is selected (for preview)
            if (_PreviewNr < 0)
            {
                return;
            }

            if (CBase.Songs.IsInCategory())
            {
                CSong song = CBase.Songs.GetVisibleSong(_PreviewNr);
                //Check if we have a valid song (song still visible, index >=0 etc is checked by framework)
                if (song == null)
                {
                    //Display at least the category
                    CCategory category = CBase.Songs.GetCategory(CBase.Songs.GetCurrentCategoryIndex());
                    //Check if we have a valid category
                    if (category == null)
                    {
                        return;
                    }
                    _CoverBig.Texture = category.CoverTextureBig;
                    _Artist.Text      = category.Name;
                    return;
                }
                _CoverBig.Texture       = song.CoverTextureBig;
                _Artist.Text            = song.Artist;
                _Title.Text             = song.Title;
                _SongYear.Text          = song.Year;
                _DuetIcon.Visible       = song.IsDuet;
                _VideoIcon.Visible      = song.VideoFileName != "";
                _MedleyCalcIcon.Visible = song.Medley.Source == EDataSource.Calculated;
                _MedleyTagIcon.Visible  = song.Medley.Source == EDataSource.Tag;

                _UpdateLength(song);
            }
            else
            {
                CCategory category = CBase.Songs.GetCategory(_PreviewNr);
                //Check if we have a valid category
                if (category == null)
                {
                    return;
                }
                _CoverBig.Texture = category.CoverTextureBig;
                _Artist.Text      = category.Name;

                int    num         = category.GetNumSongsNotSung();
                String songOrSongs = (num == 1) ? "TR_SCREENSONG_NUMSONG" : "TR_SCREENSONG_NUMSONGS";
                _Title.Text = CBase.Language.Translate(songOrSongs).Replace("%v", num.ToString());
            }
        }
예제 #23
0
        public override void Draw()
        {
            foreach (CStatic tile in _Tiles)
            {
                if (tile.Selected && _Active)
                {
                    tile.Draw(1.2f, tile.Rect.Z - 0.1f, EAspect.Crop, false);
                }
                else
                {
                    if (tile.Texture.index != _CoverTexture.index)
                    {
                        tile.Draw(1f, tile.Rect.Z, EAspect.Crop, false);
                    }
                    else
                    {
                        tile.Draw(1f, tile.Rect.Z, EAspect.Stretch, false);
                    }
                }
            }

            if (CSongs.Category >= 0)
            {
                int actsong = _PreviewSelected;
                if ((CSongs.NumVisibleSongs > actsong) && (actsong >= 0))
                {
                    CSong song = CSongs.VisibleSongs[actsong];

                    _CoverBig.Texture       = song.CoverTextureSmall;
                    _Artist.Text            = song.Artist;
                    _Title.Text             = song.Title;
                    _DuetIcon.Visible       = song.IsDuet;
                    _VideoIcon.Visible      = song.VideoFileName.Length > 0;
                    _MedleyCalcIcon.Visible = song.Medley.Source == EMedleySource.Calculated;
                    _MedleyTagIcon.Visible  = song.Medley.Source == EMedleySource.Tag;

                    float Time = CSound.GetLength(_SongStream);
                    if (song.Finish != 0)
                    {
                        Time = song.Finish;
                    }

                    Time -= song.Start;
                    int min = (int)Math.Floor(Time / 60f);
                    int sec = (int)(Time - min * 60f);
                    _SongLength.Text = min.ToString("00") + ":" + sec.ToString("00");
                }
            }
            else
            {
                int actcat = _PreviewSelected;
                if ((CSongs.NumCategories > actcat) && (actcat >= 0))
                {
                    _CoverBig.Texture = CSongs.Categories[actcat].CoverTextureSmall;
                    _Artist.Text      = CSongs.Categories[actcat].Name;

                    int num = CSongs.NumSongsInCategory(actcat);
                    if (num != 1)
                    {
                        _Title.Text = CLanguage.Translate("TR_SCREENSONG_NUMSONGS").Replace("%v", num.ToString());
                    }
                    else
                    {
                        _Title.Text = CLanguage.Translate("TR_SCREENSONG_NUMSONG").Replace("%v", num.ToString());
                    }

                    _SongLength.Text        = String.Empty;
                    _DuetIcon.Visible       = false;
                    _VideoIcon.Visible      = false;
                    _MedleyCalcIcon.Visible = false;
                    _MedleyTagIcon.Visible  = false;
                }
            }

            _TextBG.Draw();

            _CoverBig.Draw(1f, EAspect.Crop);
            if (_vidtex.color.A < 1)
            {
                _CoverBig.Draw(1f, EAspect.Crop);
            }

            if (_vidtex.index != -1 && _Video != -1)
            {
                RectangleF bounds = new RectangleF(_CoverBig.Rect.X, _CoverBig.Rect.Y, _CoverBig.Rect.W, _CoverBig.Rect.H);
                RectangleF rect   = new RectangleF(0f, 0f, _vidtex.width, _vidtex.height);
                CHelper.SetRect(bounds, ref rect, rect.Width / rect.Height, EAspect.Crop);

                CDraw.DrawTexture(_vidtex, new SRectF(rect.X, rect.Y, rect.Width, rect.Height, _CoverBig.Rect.Z),
                                  _vidtex.color, new SRectF(bounds.X, bounds.Y, bounds.Width, bounds.Height, 0f), false);
                CDraw.DrawTextureReflection(_vidtex, new SRectF(rect.X, rect.Y, rect.Width, rect.Height, _CoverBig.Rect.Z),
                                            _vidtex.color, new SRectF(bounds.X, bounds.Y, bounds.Width, bounds.Height, 0f), _CoverBig.ReflectionSpace, _CoverBig.ReflectionHeight);
            }



            _Artist.Draw();
            _Title.Draw();
            _SongLength.Draw();
            _DuetIcon.Draw();
            _VideoIcon.Draw();
            _MedleyCalcIcon.Draw();
            _MedleyTagIcon.Draw();
        }
예제 #24
0
        private void UpdateRatings()
        {
            CSong song = null;

            SPlayer[] player = new SPlayer[CGame.NumPlayer];
            if (_Round != 0)
            {
                song = CGame.GetSong(_Round);
                if (song == null)
                {
                    return;
                }

                Texts[htTexts(TextSong)].Text = song.Artist + " - " + song.Title;
                if (_Points.NumRounds > 1)
                {
                    Texts[htTexts(TextSong)].Text += " (" + _Round + "/" + _Points.NumRounds + ")";
                }
                player = _Points.GetPlayer(_Round - 1, CGame.NumPlayer);
            }
            else
            {
                Texts[htTexts(TextSong)].Text = "TR_SCREENSCORE_OVERALLSCORE";
                for (int i = 0; i < CGame.NumRounds; i++)
                {
                    SPlayer[] points = _Points.GetPlayer(i, CGame.NumPlayer);
                    for (int p = 0; p < player.Length; p++)
                    {
                        if (i < 1)
                        {
                            player[p].ProfileID  = points[p].ProfileID;
                            player[p].Name       = points[p].Name;
                            player[p].Difficulty = points[p].Difficulty;
                        }
                        player[p].Points += points[p].Points;
                    }
                }
                for (int p = 0; p < player.Length; p++)
                {
                    player[p].Points = (int)(player[p].Points / CGame.NumRounds);
                }
            }

            for (int p = 0; p < player.Length; p++)
            {
                if (song != null)
                {
                    if (!song.IsDuet)
                    {
                        Texts[htTexts(TextNames[p, CGame.NumPlayer - 1])].Text = player[p].Name;
                    }
                    else
                    if (player[p].LineNr == 0 && song.DuetPart1 != "Part 1")
                    {
                        Texts[htTexts(TextNames[p, CGame.NumPlayer - 1])].Text = player[p].Name + " (" + song.DuetPart1 + ")";
                    }
                    else if (player[p].LineNr == 1 && song.DuetPart2 != "Part 2")
                    {
                        Texts[htTexts(TextNames[p, CGame.NumPlayer - 1])].Text = player[p].Name + " (" + song.DuetPart2 + ")";
                    }
                    else
                    {
                        Texts[htTexts(TextNames[p, CGame.NumPlayer - 1])].Text = player[p].Name;
                    }
                }
                else
                {
                    Texts[htTexts(TextNames[p, CGame.NumPlayer - 1])].Text = player[p].Name;
                }

                Texts[htTexts(TextScores[p, CGame.NumPlayer - 1])].Text = ((int)Math.Round(player[p].Points)).ToString("0000") + " " + CLanguage.Translate("TR_SCREENSCORE_POINTS");
                if (CGame.NumPlayer <= 3)
                {
                    Texts[htTexts(TextRatings[p, CGame.NumPlayer - 1])].Text    = CLanguage.Translate("TR_SCREENSCORE_RATING") + ": " + CLanguage.Translate(GetRating((int)Math.Round(player[p].Points)));
                    Texts[htTexts(TextDifficulty[p, CGame.NumPlayer - 1])].Text = CLanguage.Translate("TR_SCREENSCORE_GAMEDIFFICULTY") + ": " + CLanguage.Translate(player[p].Difficulty.ToString());
                }
                else
                {
                    Texts[htTexts(TextRatings[p, CGame.NumPlayer - 1])].Text    = CLanguage.Translate(GetRating((int)Math.Round(player[p].Points)));
                    Texts[htTexts(TextDifficulty[p, CGame.NumPlayer - 1])].Text = CLanguage.Translate(player[p].Difficulty.ToString());
                }
                StaticPointsBarDrawnPoints[p] = 0.0;
                Statics[htStatics(StaticPointsBar[p, CGame.NumPlayer - 1])].Rect.H = 0;
                Statics[htStatics(StaticPointsBar[p, CGame.NumPlayer - 1])].Rect.Y = Statics[htStatics(StaticPointsBarBG[p, CGame.NumPlayer - 1])].Rect.H + Statics[htStatics(StaticPointsBarBG[p, CGame.NumPlayer - 1])].Rect.Y - Statics[htStatics(StaticPointsBar[p, CGame.NumPlayer - 1])].Rect.H;
                if (player[p].ProfileID >= 0 && player[p].ProfileID < CProfiles.NumProfiles)
                {
                    Statics[htStatics(StaticAvatar[p, CGame.NumPlayer - 1])].Texture = CProfiles.Profiles[player[p].ProfileID].Avatar.Texture;
                }
            }

            if (CConfig.ScoreAnimationTime < 1)
            {
                for (int p = 0; p < CGame.NumPlayer; p++)
                {
                    Statics[htStatics(StaticPointsBar[p, CGame.NumPlayer - 1])].Rect.H = ((float)player[p].Points) * (Statics[htStatics(StaticPointsBarBG[p, CGame.NumPlayer - 1])].Rect.H / 10000);
                    Statics[htStatics(StaticPointsBar[p, CGame.NumPlayer - 1])].Rect.Y = Statics[htStatics(StaticPointsBarBG[p, CGame.NumPlayer - 1])].Rect.H + Statics[htStatics(StaticPointsBarBG[p, CGame.NumPlayer - 1])].Rect.Y - Statics[htStatics(StaticPointsBar[p, CGame.NumPlayer - 1])].Rect.H;
                    StaticPointsBarDrawnPoints[p] = player[p].Points;
                }
            }

            timer = new Stopwatch();
            timer.Start();
        }
예제 #25
0
        public static void UpdatePoints(float time)
        {
            CSong song = _SongQueue.GetSong();

            if (song == null)
            {
                return;
            }

            float b = GetBeatFromTime(time, song.BPM, song.Gap);

            if (b <= CurrentBeatF)
            {
                return;
            }

            CurrentBeatF = b;

            MidRecordedBeat = -0.5f + GetBeatFromTime(time, song.BPM, song.Gap + CConfig.Config.Record.MicDelay / 1000f);

            for (int p = 0; p < _NumPlayers; p++)
            {
                CRecord.AnalyzeBuffer(p);
            }

            if (_LastEvalBeat >= RecordedBeat)
            {
                return;
            }

            for (int p = 0; p < _NumPlayers; p++)
            {
                for (int beat = _LastEvalBeat + 1; beat <= RecordedBeat; beat++)
                {
                    if ((_SongQueue.GetCurrentGameMode() == EGameMode.TR_GAMEMODE_MEDLEY && song.Medley.EndBeat == beat) ||
                        (_SongQueue.GetCurrentGameMode() == EGameMode.TR_GAMEMODE_SHORTSONG && song.ShortEnd.EndBeat == beat))
                    {
                        Players[p].SongFinished = true;
                    }

                    CSongLine[] lines = song.Notes.GetVoice(Players[p].VoiceNr).Lines;
                    int         line  = song.Notes.GetVoice(Players[p].VoiceNr).FindPreviousLine(beat);
                    if (line < 0 || lines[line].EndBeat < beat)
                    {
                        continue;
                    }

                    //Check for already sung
                    if (line < Players[p].SungLines.Count - 1)
                    {
                        continue; // Already sung whole line
                    }
                    if (line == Players[p].SungLines.Count - 1)
                    {
                        //We are in the last line
                        if (beat <= Players[p].SungLines[line].LastNoteBeat)
                        {
                            continue; //We already have something that ends with/after that beat
                        }
                    }

                    if (line != Players[p].CurrentLine)
                    {
                        Players[p].CurrentNote = -1;
                    }

                    Players[p].CurrentLine = line;

                    while (Players[p].SungLines.Count <= line)
                    {
                        Players[p].SungLines.Add(new CSungLine());
                    }

                    CSongNote[] notes = lines[line].Notes;
                    int         note  = lines[line].FindPreviousNote(beat);
                    if (note < 0 || notes[note].EndBeat < beat)
                    {
                        continue;
                    }

                    Players[p].CurrentNote = note;

                    if (line == lines.Length - 1 && beat == lines[line].LastNoteBeat)
                    {
                        Players[p].SongFinished = true;
                    }

                    if (notes[note].PointsForBeat > 0 && (CRecord.ToneValid(p)
#if DEBUG_HIT
                                                          || true
#endif
                                                          ))
                    {
                        int tone       = notes[note].Tone;
                        int tonePlayer = CRecord.GetTone(p);

                        while (tonePlayer - tone > 6)
                        {
                            tonePlayer -= 12;
                        }

                        while (tonePlayer - tone < -6)
                        {
                            tonePlayer += 12;
                        }

#if DEBUG_HIT
                        tonePlayer = tone;
#endif

                        Players[p].NoteDiff = Math.Abs(tone - tonePlayer);
                        bool hit = Players[p].NoteDiff <= (2 - (int)CProfiles.GetDifficulty(Players[p].ProfileID));

                        if (hit)
                        {
                            // valid
                            //CRecord.RecordSetTone(p, Tone);
                            double points = (CSettings.MaxScore - CSettings.LinebonusScore) * (double)notes[note].PointsForBeat /
                                            song.Notes.GetVoice(Players[p].VoiceNr).Points;
                            if (notes[note].Type == ENoteType.Golden)
                            {
                                Players[p].PointsGoldenNotes += points;
                            }

                            Players[p].Points += points;

                            // update player notes (sung notes)
                            if (Players[p].SungLines[line].NoteCount > 0)
                            {
                                CSungNote lastNote = Players[p].SungLines[line].LastNote;

                                if (notes[note].StartBeat == beat || lastNote.EndBeat + 1 != beat || lastNote.Tone != tone || !lastNote.Hit)
                                {
                                    Players[p].SungLines[line].AddNote(new CSungNote(beat, 1, tone, notes[note], points));
                                }
                                else
                                {
                                    Players[p].SungLines[line].IncLastNoteLength();
                                    Players[p].SungLines[line].LastNote.Points += points;
                                }
                            }
                            else
                            {
                                Players[p].SungLines[line].AddNote(new CSungNote(beat, 1, tone, notes[note], points));
                            }

                            Players[p].SungLines[line].LastNote.CheckPerfect();
                            Players[p].SungLines[line].IsPerfect(lines[line]);
                        }
                        else
                        {
                            if (Players[p].SungLines[line].NoteCount > 0)
                            {
                                CSungNote lastNote = Players[p].SungLines[line].LastNote;
                                if (lastNote.Tone != tonePlayer || lastNote.EndBeat + 1 != beat || lastNote.Hit)
                                {
                                    Players[p].SungLines[line].AddNote(new CSungNote(beat, 1, tonePlayer));
                                }
                                else
                                {
                                    Players[p].SungLines[line].IncLastNoteLength();
                                }
                            }
                            else
                            {
                                Players[p].SungLines[line].AddNote(new CSungNote(beat, 1, tonePlayer));
                            }
                        }
                    }

                    // Line Bonus
                    int numLinesWithPoints = song.Notes.GetNumLinesWithPoints(Players[p].VoiceNr);
                    if (beat == lines[line].LastNoteBeat && lines[line].Points > 0 && numLinesWithPoints > 0)
                    {
                        double factor = Players[p].SungLines[line].Points / (double)lines[line].Points;
                        if (factor <= 0.4)
                        {
                            factor = 0.0;
                        }
                        else if (factor >= 0.9)
                        {
                            factor = 1.0;
                        }
                        else
                        {
                            factor -= 0.4;
                            factor *= 2;
                            factor *= factor;
                        }

                        double points = CSettings.LinebonusScore * factor / numLinesWithPoints;
                        Players[p].Points                      += points;
                        Players[p].PointsLineBonus             += points;
                        Players[p].SungLines[line].BonusPoints += points;
                    }
                }
            }
            _LastEvalBeat = RecordedBeat;
        }
예제 #26
0
파일: CMain.cs 프로젝트: da-ka/Vocaluxe
 public void LoadPreview(CSong song, float start = -1f)
 {
     CBackgroundMusic.LoadPreview(song, start);
 }
예제 #27
0
파일: CMain.cs 프로젝트: da-ka/Vocaluxe
 public CTextureRef GenerateCover(string text, ECoverGeneratorType type, CSong firstSong)
 {
     return(CCover.GenerateCover(text, type, firstSong));
 }
예제 #28
0
파일: CCover.cs 프로젝트: da-ka/Vocaluxe
        public static CTextureRef GenerateCover(string text, ECoverGeneratorType type, CSong firstSong)
        {
            CTextureRef texture = Cover(text);

            if (texture != NoCover)
            {
                return(texture);
            }
            texture = CDraw.CopyTexture(NoCover);
            Task.Factory.StartNew(() =>
            {
                _CancelToken.Token.ThrowIfCancellationRequested();
                Bitmap coverBmp = !_CoverGenerators.ContainsKey(type)
                                          ? null : _CoverGenerators[type].GetCover(text, firstSong != null ? Path.Combine(firstSong.Folder, firstSong.CoverFileName) : null);
                _CancelToken.Token.ThrowIfCancellationRequested();
                if (coverBmp == null && _CoverGenerators.ContainsKey(ECoverGeneratorType.Default))
                {
                    coverBmp = _CoverGenerators[ECoverGeneratorType.Default].GetCover(text, firstSong != null ? Path.Combine(firstSong.Folder, firstSong.CoverFileName) : null);
                }
                _CancelToken.Token.ThrowIfCancellationRequested();
                if (coverBmp != null)
                {
                    CDraw.EnqueueTextureUpdate(texture, coverBmp);
                }
                _CancelToken.Token.ThrowIfCancellationRequested();
            }, _CancelToken.Token);
            lock (_Covers)
            {
                _Covers.Add(text, texture);
            }
            return(texture);
        }
예제 #29
0
파일: CGame.cs 프로젝트: winterdl/Vocaluxe
        public static void UpdatePoints(float Time)
        {
            bool DEBUG_HIT = false;

            CSong song = _GameMode.GetSong();

            if (song == null)
            {
                return;
            }

            float b = GetBeatFromTime(Time, song.BPM, song.Gap);

            if (b <= _Beat)
            {
                return;
            }

            _Beat        = b;
            _CurrentBeat = (int)Math.Floor(_Beat);

            _MidBeatD     = -0.5f + GetBeatFromTime(Time, song.BPM, song.Gap + CConfig.MicDelay / 1000f);
            _CurrentBeatD = (int)Math.Floor(_MidBeatD);

            for (int p = 0; p < _NumPlayer; p++)
            {
                CSound.AnalyzeBuffer(p);
            }

            if (_OldBeatD >= _CurrentBeatD)
            {
                return;
            }

            for (int p = 0; p < _NumPlayer; p++)
            {
                for (int beat = _OldBeatD + 1; beat <= _CurrentBeatD; beat++)
                {
                    if ((_GameMode.GetCurrentGameMode() == EGameMode.TR_GAMEMODE_MEDLEY && song.Medley.EndBeat == beat) ||
                        (_GameMode.GetCurrentGameMode() == EGameMode.TR_GAMEMODE_SHORTSONG && song.ShortEnd == beat))
                    {
                        _Player[p].SongFinished = true;
                    }

                    CLine[] lines = song.Notes.GetLines(_Player[p].LineNr).Line;
                    int     Line  = -1;

                    for (int j = 0; j < lines.Length; j++)
                    {
                        if (beat >= lines[j].StartBeat && beat <= lines[j].EndBeat)
                        {
                            Line = j;
                            break;
                        }
                    }

                    if (Line >= 0)
                    {
                        if (Line != _Player[p].CurrentLine)
                        {
                            _Player[p].CurrentNote = -1;
                        }

                        _Player[p].CurrentLine = Line;

                        while (_Player[p].SingLine.Count <= Line)
                        {
                            _Player[p].SingLine.Add(new CLine());
                        }

                        CNote[] notes = lines[Line].Notes;
                        int     Note  = -1;
                        for (int j = 0; j < notes.Length; j++)
                        {
                            if (beat >= notes[j].StartBeat && beat <= notes[j].EndBeat)
                            {
                                Note = j;
                                break;
                            }
                        }

                        if (Note >= 0)
                        {
                            _Player[p].CurrentNote = Note;

                            if (Line == lines.Length - 1)
                            {
                                if (Note == lines[Line].NoteCount - 1)
                                {
                                    if (notes[Note].EndBeat == beat)
                                    {
                                        _Player[p].SongFinished = true;
                                    }
                                }
                            }

                            if (notes[Note].PointsForBeat > 0 && (CSound.RecordToneValid(p) || DEBUG_HIT))
                            {
                                int Tone       = notes[Note].Tone;
                                int TonePlayer = CSound.RecordGetTone(p);

                                while (TonePlayer - Tone > 6)
                                {
                                    TonePlayer -= 12;
                                }

                                while (TonePlayer - Tone < -6)
                                {
                                    TonePlayer += 12;
                                }

                                if (DEBUG_HIT)
                                {
                                    TonePlayer = Tone;
                                }

                                _Player[p].NoteDiff = Math.Abs(Tone - TonePlayer);
                                if (_Player[p].NoteDiff <= (2 - (int)_Player[p].Difficulty))
                                {
                                    // valid
                                    //CSound.RecordSetTone(p, Tone);
                                    double points = (CSettings.MaxScore - CSettings.LinebonusScore) * (double)notes[Note].PointsForBeat / (double)song.Notes.GetLines(_Player[p].LineNr).Points;
                                    if (notes[Note].NoteType == ENoteType.Golden)
                                    {
                                        _Player[p].PointsGoldenNotes += points;
                                    }

                                    _Player[p].Points += points;

                                    // update player notes (sung notes)
                                    if (_Player[p].SingLine[Line].NoteCount > 0)
                                    {
                                        CNote nt = _Player[p].SingLine[Line].LastNote;
                                        if (notes[Note].StartBeat == beat || nt.EndBeat + 1 != beat || nt.Tone != Tone)
                                        {
                                            _Player[p].SingLine[Line].AddNote(new CNote(beat, 1, Tone, String.Empty, true, notes[Note].NoteType));
                                        }
                                        else
                                        {
                                            _Player[p].SingLine[Line].IncLastNoteLength();
                                        }
                                    }
                                    else
                                    {
                                        _Player[p].SingLine[Line].AddNote(new CNote(beat, 1, Tone, String.Empty, true, notes[Note].NoteType));
                                    }

                                    _Player[p].SingLine[Line].LastNote.IsPerfect(notes[Note]);
                                    _Player[p].SingLine[Line].IsPerfect(lines[Line]);
                                }
                                else
                                {
                                    if (_Player[p].SingLine[Line].NoteCount > 0)
                                    {
                                        CNote nt = _Player[p].SingLine[Line].LastNote;
                                        if (nt.EndBeat + 1 != beat || nt.Hit)
                                        {
                                            _Player[p].SingLine[Line].AddNote(new CNote(beat, 1, TonePlayer, String.Empty, false, ENoteType.Freestyle));
                                        }
                                        else
                                        {
                                            if (nt.Tone == TonePlayer && nt.EndBeat + 1 == beat)
                                            {
                                                _Player[p].SingLine[Line].IncLastNoteLength();
                                            }
                                            else
                                            {
                                                _Player[p].SingLine[Line].AddNote(new CNote(beat, 1, TonePlayer, String.Empty, false, ENoteType.Freestyle));
                                            }
                                        }
                                    }
                                    else
                                    {
                                        _Player[p].SingLine[Line].AddNote(new CNote(beat, 1, TonePlayer, String.Empty, false, ENoteType.Freestyle));
                                    }
                                }
                            }

                            // Line Bonus
                            int NumLinesWithPoints = song.Notes.GetNumLinesWithPoints(_Player[p].LineNr);
                            if (Note == lines[Line].NoteCount - 1 && NumLinesWithPoints > 0)
                            {
                                if (notes[Note].EndBeat == beat && lines[Line].Points > 0f)
                                {
                                    double factor = (double)_Player[p].SingLine[Line].Points / (double)lines[Line].Points;
                                    if (factor < 0.4)
                                    {
                                        factor = 0.0;
                                    }
                                    else if (factor > 0.9)
                                    {
                                        factor = 1.0;
                                    }
                                    else
                                    {
                                        factor -= 0.4;
                                        factor *= 2;
                                        factor *= factor;
                                    }

                                    double points = CSettings.LinebonusScore * factor * 1f / NumLinesWithPoints;
                                    _Player[p].Points          += points;
                                    _Player[p].PointsLineBonus += points;
                                }
                            }
                        }
                    }
                }
            }
            _OldBeatD = _CurrentBeatD;
        }
예제 #30
0
파일: CGameMode.cs 프로젝트: da-ka/Vocaluxe
 protected abstract CSong _PrepareSong(CSong song);