1375 lines
54 KiB
C#
1375 lines
54 KiB
C#
#region license
|
|
// /*
|
|
// This file is part of Vocaluxe.
|
|
//
|
|
// Vocaluxe is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Vocaluxe is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
|
|
// */
|
|
#endregion
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Windows.Forms;
|
|
using Vocaluxe.Base;
|
|
using VocaluxeLib.Menu;
|
|
using VocaluxeLib.Menu.SingNotes;
|
|
using VocaluxeLib.Menu.SongMenu;
|
|
|
|
namespace Vocaluxe.Screens
|
|
{
|
|
class CScreenSing : CMenu
|
|
{
|
|
// Version number for theme files. Increment it, if you've changed something on the theme files!
|
|
protected override int _ScreenVersion
|
|
{
|
|
get { return 6; }
|
|
}
|
|
|
|
private struct STimeRect
|
|
{
|
|
public CStatic Rect;
|
|
public float StartBeat;
|
|
public float EndBeat;
|
|
}
|
|
|
|
private const string _TextSongName = "TextSongName";
|
|
private const string _TextTime = "TextTime";
|
|
private const string _TextPause = "TextPause";
|
|
private const string _TextDuetName1 = "TextDuetName1";
|
|
private const string _TextDuetName2 = "TextDuetName2";
|
|
private string[,] _TextScores;
|
|
private string[,] _TextNames;
|
|
|
|
private const string _StaticSongText = "StaticSongText";
|
|
private const string _StaticLyrics = "StaticLyrics";
|
|
private const string _StaticLyricsDuet = "StaticLyricsDuet";
|
|
private const string _StaticLyricsTop = "StaticLyricsTop";
|
|
private const string _StaticTimeBar = "StaticTimeBar";
|
|
private const string _StaticTimeLine = "StaticTimeLine";
|
|
private const string _StaticTimeLineExpandedNormal = "StaticTimeLineExpandedNormal";
|
|
private const string _StaticTimeLineExpandedHighlighted = "StaticTimeLineExpandedHighlighted";
|
|
private const string _StaticTimePointer = "StaticTimePointer";
|
|
private const string _StaticLyricHelper = "StaticLyricHelper";
|
|
private const string _StaticLyricHelperDuet = "StaticLyricHelperDuet";
|
|
private const string _StaticLyricHelperTop = "StaticLyricHelperTop";
|
|
private const string _StaticPauseBG = "StaticPauseBG";
|
|
|
|
private string[,] _StaticScores;
|
|
private string[,] _StaticAvatars;
|
|
|
|
private const string _ButtonCancel = "ButtonCancel";
|
|
private const string _ButtonContinue = "ButtonContinue";
|
|
private const string _ButtonSkip = "ButtonSkip";
|
|
|
|
private const string _LyricMain = "LyricMain";
|
|
private const string _LyricSub = "LyricSub";
|
|
private const string _LyricMainDuet = "LyricMainDuet";
|
|
private const string _LyricSubDuet = "LyricSubDuet";
|
|
private const string _LyricMainTop = "LyricMainTop";
|
|
private const string _LyricSubTop = "LyricSubTop";
|
|
|
|
private const string _SingBars = "SingBars";
|
|
|
|
private SRectF _TimeLineRect;
|
|
private List<STimeRect> _TimeRects;
|
|
private bool _FadeOut;
|
|
|
|
private int _CurrentBeat;
|
|
private int _CurrentStream = -1;
|
|
//private int _NextStream = -1;
|
|
private float _Volume = 100f;
|
|
private int _CurrentVideo = -1;
|
|
private EAspect _VideoAspect = EAspect.Crop;
|
|
private STexture _CurrentVideoTexture = new STexture(-1);
|
|
private STexture _CurrentWebcamFrameTexture = new STexture(-1);
|
|
private STexture _Background = new STexture(-1);
|
|
|
|
private float _CurrentTime;
|
|
private float _FinishTime;
|
|
|
|
private float _TimeToFirstNote;
|
|
private float _RemainingTimeToFirstNote;
|
|
private float _TimeToFirstNoteDuet;
|
|
private float _RemainingTimeToFirstNoteDuet;
|
|
|
|
private readonly int[] _NoteLines = new int[CSettings.MaxNumPlayer];
|
|
|
|
private Stopwatch _TimerSongText;
|
|
private Stopwatch _TimerDuetText1;
|
|
private Stopwatch _TimerDuetText2;
|
|
|
|
private bool _Pause;
|
|
private bool _Webcam;
|
|
|
|
public override void Init()
|
|
{
|
|
base.Init();
|
|
|
|
List<string> texts = new List<string>();
|
|
texts.Add(_TextSongName);
|
|
texts.Add(_TextTime);
|
|
texts.Add(_TextPause);
|
|
texts.Add(_TextDuetName1);
|
|
texts.Add(_TextDuetName2);
|
|
_BuildTextStrings(ref texts);
|
|
_ThemeTexts = texts.ToArray();
|
|
|
|
List<string> statics = new List<string>();
|
|
statics.Add(_StaticSongText);
|
|
statics.Add(_StaticLyrics);
|
|
statics.Add(_StaticLyricsDuet);
|
|
statics.Add(_StaticLyricsTop);
|
|
statics.Add(_StaticTimeBar);
|
|
statics.Add(_StaticTimeLine);
|
|
statics.Add(_StaticTimeLineExpandedNormal);
|
|
statics.Add(_StaticTimeLineExpandedHighlighted);
|
|
statics.Add(_StaticTimePointer);
|
|
statics.Add(_StaticLyricHelper);
|
|
statics.Add(_StaticLyricHelperDuet);
|
|
statics.Add(_StaticLyricHelperTop);
|
|
statics.Add(_StaticPauseBG);
|
|
_BuildStaticStrings(ref statics);
|
|
_ThemeStatics = statics.ToArray();
|
|
|
|
List<string> buttons = new List<string>();
|
|
buttons.Add(_ButtonCancel);
|
|
buttons.Add(_ButtonContinue);
|
|
buttons.Add(_ButtonSkip);
|
|
_ThemeButtons = buttons.ToArray();
|
|
|
|
_ThemeLyrics = new string[] {_LyricMain, _LyricSub, _LyricMainDuet, _LyricSubDuet, _LyricMainTop, _LyricSubTop};
|
|
_ThemeSingNotes = new string[] {_SingBars};
|
|
|
|
_TimeRects = new List<STimeRect>();
|
|
_TimerSongText = new Stopwatch();
|
|
_TimerDuetText1 = new Stopwatch();
|
|
_TimerDuetText2 = new Stopwatch();
|
|
}
|
|
|
|
public override void LoadTheme(string xmlPath)
|
|
{
|
|
base.LoadTheme(xmlPath);
|
|
|
|
_Statics[_StaticTimeLine].Visible = false;
|
|
_Statics[_StaticTimeLineExpandedNormal].Visible = false;
|
|
_Statics[_StaticTimeLineExpandedHighlighted].Visible = false;
|
|
_Statics[_StaticPauseBG].Visible = false;
|
|
_Texts[_TextPause].Visible = false;
|
|
|
|
_Statics[_StaticPauseBG].Visible = false;
|
|
_Texts[_TextPause].Visible = false;
|
|
|
|
_Buttons[_ButtonCancel].Visible = false;
|
|
_Buttons[_ButtonContinue].Visible = false;
|
|
}
|
|
|
|
public override bool HandleInput(SKeyEvent keyEvent)
|
|
{
|
|
base.HandleInput(keyEvent);
|
|
|
|
if (keyEvent.KeyPressed)
|
|
{
|
|
//
|
|
}
|
|
else
|
|
{
|
|
switch (keyEvent.Key)
|
|
{
|
|
case Keys.Escape:
|
|
_TogglePause();
|
|
if (_Pause)
|
|
_SetInteractionToButton(_Buttons[_ButtonCancel]);
|
|
break;
|
|
|
|
case Keys.P:
|
|
_TogglePause();
|
|
if (_Pause)
|
|
_SetInteractionToButton(_Buttons[_ButtonContinue]);
|
|
break;
|
|
|
|
case Keys.T:
|
|
int mode = (int)CConfig.TimerMode;
|
|
|
|
mode++;
|
|
if (mode > Enum.GetNames(typeof(ETimerMode)).Length - 1)
|
|
mode = 0;
|
|
CConfig.TimerMode = (ETimerMode)mode;
|
|
break;
|
|
|
|
case Keys.I:
|
|
mode = (int)CConfig.PlayerInfo;
|
|
|
|
mode++;
|
|
if (mode > Enum.GetNames(typeof(EPlayerInfo)).Length - 1)
|
|
mode = 0;
|
|
CConfig.PlayerInfo = (EPlayerInfo)mode;
|
|
CConfig.SaveConfig();
|
|
_SetVisibility();
|
|
if (CGame.GetSong() != null)
|
|
_SetDuetLyricsVisibility(CGame.GetSong().IsDuet); //make sure duet lyrics remain visible
|
|
break;
|
|
|
|
case Keys.S:
|
|
if (CGame.NumRounds > CGame.RoundNr)
|
|
{
|
|
if (keyEvent.ModCtrl)
|
|
_LoadNextSong();
|
|
}
|
|
break;
|
|
case Keys.W:
|
|
if (CWebcam.IsDeviceAvailable())
|
|
{
|
|
_Webcam = !_Webcam;
|
|
if (_Webcam)
|
|
CWebcam.Start();
|
|
else
|
|
CWebcam.Stop();
|
|
}
|
|
break;
|
|
case Keys.Enter:
|
|
if (_Buttons[_ButtonContinue].Selected && _Pause)
|
|
_TogglePause();
|
|
if (_Buttons[_ButtonCancel].Selected && _Pause)
|
|
_Stop();
|
|
if (_Buttons[_ButtonSkip].Selected && _Pause)
|
|
{
|
|
_LoadNextSong();
|
|
_TogglePause();
|
|
}
|
|
break;
|
|
|
|
case Keys.Add:
|
|
case Keys.PageUp:
|
|
if (keyEvent.ModShift)
|
|
{
|
|
CConfig.GameMusicVolume = CConfig.GameMusicVolume + 5;
|
|
if (CConfig.GameMusicVolume > 100)
|
|
CConfig.GameMusicVolume = 100;
|
|
CConfig.SaveConfig();
|
|
ApplyVolume();
|
|
}
|
|
break;
|
|
|
|
case Keys.Subtract:
|
|
case Keys.PageDown:
|
|
if (keyEvent.ModShift)
|
|
{
|
|
CConfig.GameMusicVolume = CConfig.GameMusicVolume - 5;
|
|
if (CConfig.GameMusicVolume < 0)
|
|
CConfig.GameMusicVolume = 0;
|
|
CConfig.SaveConfig();
|
|
ApplyVolume();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public override bool HandleMouse(SMouseEvent mouseEvent)
|
|
{
|
|
base.HandleMouse(mouseEvent);
|
|
|
|
if (mouseEvent.RB)
|
|
{
|
|
_TogglePause();
|
|
if (_Pause)
|
|
_SetInteractionToButton(_Buttons[_ButtonContinue]);
|
|
}
|
|
|
|
if (mouseEvent.LB && _IsMouseOver(mouseEvent) && _Pause)
|
|
{
|
|
if (_Buttons[_ButtonContinue].Selected && _Pause)
|
|
_TogglePause();
|
|
|
|
if (_Buttons[_ButtonCancel].Selected && _Pause)
|
|
_Stop();
|
|
|
|
if (_Buttons[_ButtonSkip].Selected && _Pause)
|
|
{
|
|
_LoadNextSong();
|
|
_TogglePause();
|
|
}
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
public override bool UpdateGame()
|
|
{
|
|
bool finish = false;
|
|
if (CSound.IsPlaying(_CurrentStream) || CSound.IsPaused(_CurrentStream))
|
|
{
|
|
_CurrentTime = CSound.GetPosition(_CurrentStream);
|
|
|
|
if (_FinishTime >0.001 && _CurrentTime >= _FinishTime)
|
|
finish = true;
|
|
}
|
|
else
|
|
finish = true;
|
|
|
|
if (finish)
|
|
_LoadNextSong();
|
|
|
|
_UpdateSongText();
|
|
_UpdateDuetText();
|
|
if (_FadeOut)
|
|
return true;
|
|
|
|
_UpdateTimeLine();
|
|
|
|
CGame.UpdatePoints(_CurrentTime);
|
|
_UpdateLyrics();
|
|
|
|
float[] alpha = _CalcFadingAlpha();
|
|
if (alpha != null)
|
|
{
|
|
_Lyrics[_LyricMain].Alpha = alpha[0];
|
|
_Lyrics[_LyricSub].Alpha = alpha[1];
|
|
|
|
_Lyrics[_LyricMainTop].Alpha = alpha[0];
|
|
_Lyrics[_LyricSubTop].Alpha = alpha[1];
|
|
|
|
_Statics[_StaticLyrics].Alpha = alpha[0];
|
|
_Statics[_StaticLyricsTop].Alpha = alpha[0];
|
|
|
|
_Statics[_StaticLyricHelper].Alpha = alpha[0];
|
|
_Statics[_StaticLyricHelperTop].Alpha = alpha[0];
|
|
|
|
for (int p = 0; p < CGame.NumPlayer; p++)
|
|
{
|
|
_SingNotes[_SingBars].SetAlpha(_NoteLines[p], alpha[CGame.Player[p].LineNr * 2]);
|
|
if (CConfig.FadePlayerInfo == EFadePlayerInfo.TR_CONFIG_FADEPLAYERINFO_INFO || CConfig.FadePlayerInfo == EFadePlayerInfo.TR_CONFIG_FADEPLAYERINFO_ALL)
|
|
{
|
|
_Statics[_StaticAvatars[p, CGame.NumPlayer - 1]].Alpha = alpha[CGame.Player[p].LineNr * 2];
|
|
_Texts[_TextNames[p, CGame.NumPlayer - 1]].Alpha = alpha[CGame.Player[p].LineNr * 2];
|
|
}
|
|
if (CConfig.FadePlayerInfo == EFadePlayerInfo.TR_CONFIG_FADEPLAYERINFO_ALL)
|
|
{
|
|
_Statics[_StaticScores[p, CGame.NumPlayer - 1]].Alpha = alpha[CGame.Player[p].LineNr * 2];
|
|
_Statics[_StaticAvatars[p, CGame.NumPlayer - 1]].Alpha = alpha[CGame.Player[p].LineNr * 2];
|
|
_Texts[_TextNames[p, CGame.NumPlayer - 1]].Alpha = alpha[CGame.Player[p].LineNr * 2];
|
|
_Texts[_TextScores[p, CGame.NumPlayer - 1]].Alpha = alpha[CGame.Player[p].LineNr * 2];
|
|
}
|
|
}
|
|
|
|
if (alpha.Length > 2)
|
|
{
|
|
_Lyrics[_LyricMainDuet].Alpha = alpha[0];
|
|
_Lyrics[_LyricSubDuet].Alpha = alpha[1];
|
|
|
|
_Statics[_StaticLyricsDuet].Alpha = alpha[0];
|
|
_Statics[_StaticLyricHelperDuet].Alpha = alpha[0];
|
|
|
|
_Lyrics[_LyricMain].Alpha = alpha[2];
|
|
_Lyrics[_LyricSub].Alpha = alpha[3];
|
|
|
|
_Statics[_StaticLyrics].Alpha = alpha[2];
|
|
_Statics[_StaticLyricHelper].Alpha = alpha[2];
|
|
}
|
|
}
|
|
|
|
|
|
for (int p = 0; p < CGame.NumPlayer; p++)
|
|
{
|
|
if (CGame.Player[p].Points < 10000)
|
|
_Texts[_TextScores[p, CGame.NumPlayer - 1]].Text = CGame.Player[p].Points.ToString("0000");
|
|
else
|
|
_Texts[_TextScores[p, CGame.NumPlayer - 1]].Text = CGame.Player[p].Points.ToString("00000");
|
|
}
|
|
|
|
if (_CurrentVideo != -1 && !_FadeOut && CConfig.VideosInSongs == EOffOn.TR_CONFIG_ON)
|
|
{
|
|
float vtime;
|
|
CVideo.VdGetFrame(_CurrentVideo, ref _CurrentVideoTexture, _CurrentTime, out vtime);
|
|
}
|
|
|
|
if (_Webcam)
|
|
CWebcam.GetFrame(ref _CurrentWebcamFrameTexture);
|
|
|
|
return true;
|
|
}
|
|
|
|
public override void OnShow()
|
|
{
|
|
base.OnShow();
|
|
|
|
_FadeOut = false;
|
|
|
|
_CurrentVideo = -1;
|
|
_CurrentVideoTexture = new STexture(-1);
|
|
_CurrentWebcamFrameTexture = new STexture(-1);
|
|
_CurrentBeat = -100;
|
|
_CurrentTime = 0f;
|
|
_FinishTime = 0f;
|
|
_TimeToFirstNote = 0f;
|
|
_TimeToFirstNoteDuet = 0f;
|
|
_Pause = false;
|
|
|
|
_TimeRects.Clear();
|
|
|
|
_SingNotes[_SingBars].Reset();
|
|
for (int i = 0; i < CSettings.MaxNumPlayer; i++)
|
|
_NoteLines[i] = -1;
|
|
|
|
foreach (CLyric lyric in _Lyrics)
|
|
lyric.LyricStyle = CConfig.LyricStyle;
|
|
|
|
for (int p = 0; p < CGame.NumPlayer; p++)
|
|
_Statics[_StaticAvatars[p, CGame.NumPlayer - 1]].Aspect = EAspect.Crop;
|
|
_SetVisibility();
|
|
|
|
_UpdateAvatars();
|
|
_UpdateNames();
|
|
|
|
CBackgroundMusic.Disabled = true;
|
|
_CloseSong();
|
|
}
|
|
|
|
public override void OnShowFinish()
|
|
{
|
|
base.OnShowFinish();
|
|
|
|
CGame.Start();
|
|
_LoadNextSong();
|
|
CBackgroundMusic.Disabled = true;
|
|
}
|
|
|
|
public override bool Draw()
|
|
{
|
|
if (_Active)
|
|
{
|
|
if (_CurrentVideo != -1 && CConfig.VideosInSongs == EOffOn.TR_CONFIG_ON && !_Webcam)
|
|
{
|
|
RectangleF bounds = new RectangleF(0, 0, CSettings.RenderW, CSettings.RenderH);
|
|
RectangleF rect = new RectangleF(0f, 0f, _CurrentVideoTexture.Width, _CurrentVideoTexture.Height);
|
|
CHelper.SetRect(bounds, out rect, rect.Width / rect.Height, _VideoAspect);
|
|
|
|
CDraw.DrawTexture(_CurrentVideoTexture, new SRectF(rect.X, rect.Y, rect.Width, rect.Height, 0f),
|
|
_CurrentVideoTexture.Color, new SRectF(bounds.X, bounds.Y, bounds.Width, bounds.Height, 0f), false);
|
|
}
|
|
else if (_Webcam)
|
|
{
|
|
RectangleF bounds = new RectangleF(0, 0, CSettings.RenderW, CSettings.RenderH);
|
|
RectangleF rect = new RectangleF(0f, 0f, _CurrentWebcamFrameTexture.Width, _CurrentWebcamFrameTexture.Height);
|
|
CHelper.SetRect(bounds, out rect, rect.Width / rect.Height, _VideoAspect);
|
|
|
|
CDraw.DrawTexture(_CurrentWebcamFrameTexture, new SRectF(rect.X, rect.Y, rect.Width, rect.Height, 0f),
|
|
_CurrentVideoTexture.Color, new SRectF(bounds.X, bounds.Y, bounds.Width, bounds.Height, 0f), false);
|
|
}
|
|
else
|
|
{
|
|
// Draw Background
|
|
RectangleF bounds = new RectangleF(0, 0, CSettings.RenderW, CSettings.RenderH);
|
|
RectangleF rect = new RectangleF(0f, 0f, _Background.Width, _Background.Height);
|
|
CHelper.SetRect(bounds, out rect, rect.Width / rect.Height, EAspect.Crop);
|
|
|
|
CDraw.DrawTexture(_Background, new SRectF(rect.X, rect.Y, rect.Width, rect.Height, 0f),
|
|
_Background.Color, new SRectF(bounds.X, bounds.Y, bounds.Width, bounds.Height, 0f), false);
|
|
}
|
|
}
|
|
|
|
_DrawBG();
|
|
|
|
foreach (CStatic stat in _Statics)
|
|
stat.Draw();
|
|
|
|
foreach (CText text in _Texts)
|
|
text.Draw();
|
|
|
|
switch (CConfig.TimerLook)
|
|
{
|
|
case ETimerLook.TR_CONFIG_TIMERLOOK_NORMAL:
|
|
CDraw.DrawTexture(_Statics[_StaticTimeLine].Texture, _Statics[_StaticTimeLine].Rect, new SColorF(1, 1, 1, 1), _TimeLineRect);
|
|
break;
|
|
case ETimerLook.TR_CONFIG_TIMERLOOK_EXPANDED:
|
|
for (int i = 0; i < _TimeRects.Count; i++)
|
|
CDraw.DrawTexture(_TimeRects[i].Rect.Texture, _Statics[_StaticTimeLine].Rect, _TimeRects[i].Rect.Color, _TimeRects[i].Rect.Rect);
|
|
break;
|
|
}
|
|
|
|
_Lyrics[_LyricSub].Draw(-100);
|
|
_Lyrics[_LyricMain].Draw(CGame.Beat);
|
|
|
|
_Lyrics[_LyricSubDuet].Draw(-100);
|
|
_Lyrics[_LyricMainDuet].Draw(CGame.Beat);
|
|
|
|
_Lyrics[_LyricSubTop].Draw(-100);
|
|
_Lyrics[_LyricMainTop].Draw(CGame.Beat);
|
|
|
|
|
|
for (int i = 0; i < CGame.NumPlayer; i++)
|
|
_SingNotes[_SingBars].Draw(_NoteLines[i], CGame.Player[i].SingLine, i);
|
|
|
|
_DrawLyricHelper();
|
|
|
|
if (_Pause)
|
|
{
|
|
_Statics[_StaticPauseBG].ForceDraw();
|
|
_Texts[_TextPause].ForceDraw();
|
|
|
|
foreach (CButton button in _Buttons)
|
|
button.Draw();
|
|
|
|
foreach (CSelectSlide slide in _SelectSlides)
|
|
slide.Draw();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public override void OnClose()
|
|
{
|
|
base.OnClose();
|
|
CBackgroundMusic.Disabled = false;
|
|
_CloseSong();
|
|
}
|
|
|
|
public override void ApplyVolume()
|
|
{
|
|
CSound.SetStreamVolumeMax(_CurrentStream, CConfig.GameMusicVolume);
|
|
}
|
|
|
|
private void _CloseSong()
|
|
{
|
|
CSound.FadeAndStop(_CurrentStream, 0f, 0.5f);
|
|
CSound.RecordStop();
|
|
if (_CurrentVideo != -1)
|
|
{
|
|
CVideo.VdClose(_CurrentVideo);
|
|
_CurrentVideo = -1;
|
|
CDraw.RemoveTexture(ref _CurrentVideoTexture);
|
|
}
|
|
CDraw.RemoveTexture(ref _Background);
|
|
|
|
_Lyrics[_LyricMain].Clear();
|
|
_Lyrics[_LyricSub].Clear();
|
|
_Lyrics[_LyricMainDuet].Clear();
|
|
_Lyrics[_LyricSubDuet].Clear();
|
|
_Lyrics[_LyricMainTop].Clear();
|
|
_Lyrics[_LyricSubTop].Clear();
|
|
_Texts[_TextSongName].Text = String.Empty;
|
|
_Texts[_TextDuetName1].Text = String.Empty;
|
|
_Texts[_TextDuetName2].Text = String.Empty;
|
|
GC.Collect();
|
|
}
|
|
|
|
private void _LoadNextSong()
|
|
{
|
|
_CloseSong();
|
|
|
|
CGame.NextRound();
|
|
|
|
if (CGame.IsFinished())
|
|
{
|
|
_FinishedSinging();
|
|
return;
|
|
}
|
|
|
|
CSong song = CGame.GetSong();
|
|
|
|
if (song == null)
|
|
{
|
|
CLog.LogError("Critical Error! ScreenSing.LoadNextSong() song is null!");
|
|
return;
|
|
}
|
|
|
|
string songname = song.Artist + " - " + song.Title;
|
|
int rounds = CGame.GetNumSongs();
|
|
if (rounds > 1)
|
|
songname += " (" + CGame.RoundNr + "/" + rounds + ")";
|
|
_Texts[_TextSongName].Text = songname;
|
|
|
|
_CurrentStream = CSound.Load(song.GetMP3(), true);
|
|
CSound.SetStreamVolumeMax(_CurrentStream, CConfig.GameMusicVolume);
|
|
CSound.SetStreamVolume(_CurrentStream, _Volume);
|
|
CSound.SetPosition(_CurrentStream, song.Start);
|
|
_CurrentTime = song.Start;
|
|
_FinishTime = song.Finish;
|
|
_TimeToFirstNote = 0f;
|
|
_TimeToFirstNoteDuet = 0f;
|
|
int[] duetPlayer = new int[CGame.NumPlayer];
|
|
if (song.IsDuet)
|
|
{
|
|
//Save duet-assignment before resetting
|
|
for (int i = 0; i < duetPlayer.Length; i++)
|
|
duetPlayer[i] = CGame.Player[i].LineNr;
|
|
}
|
|
CGame.ResetPlayer();
|
|
|
|
CDraw.RemoveTexture(ref _CurrentVideoTexture);
|
|
|
|
if (song.VideoFileName != "")
|
|
{
|
|
_CurrentVideo = CVideo.VdLoad(Path.Combine(song.Folder, song.VideoFileName));
|
|
CVideo.VdSkip(_CurrentVideo, song.Start, song.VideoGap);
|
|
_VideoAspect = song.VideoAspect;
|
|
}
|
|
|
|
CDraw.RemoveTexture(ref _Background);
|
|
if (song.BackgroundFileName != "")
|
|
_Background = CDraw.AddTexture(Path.Combine(song.Folder, song.BackgroundFileName));
|
|
|
|
_SingNotes[_SingBars].Reset();
|
|
|
|
|
|
if (song.IsDuet)
|
|
{
|
|
_Texts[_TextDuetName1].Text = song.DuetPart1;
|
|
_Texts[_TextDuetName2].Text = song.DuetPart2;
|
|
//More than one song: Player is not assigned to line by user
|
|
//Otherwise, this is done by CScreenNames
|
|
if (CGame.GetNumSongs() > 1)
|
|
{
|
|
for (int i = 0; i < CGame.NumPlayer; i++)
|
|
{
|
|
if ((i % 2) == 0)
|
|
CGame.Player[i].LineNr = 1;
|
|
else
|
|
CGame.Player[i].LineNr = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < CGame.NumPlayer; i++)
|
|
CGame.Player[i].LineNr = duetPlayer[i];
|
|
}
|
|
}
|
|
_SetDuetLyricsVisibility(song.IsDuet);
|
|
|
|
for (int p = 0; p < CGame.NumPlayer; p++)
|
|
{
|
|
_NoteLines[p] = _SingNotes[_SingBars].AddPlayer(
|
|
_SingNotes[_SingBars].BarPos[p, CGame.NumPlayer - 1],
|
|
CTheme.GetPlayerColor(p + 1),
|
|
p);
|
|
}
|
|
|
|
/*
|
|
case 4:
|
|
NoteLines[0] = SingNotes[SingBars].AddPlayer(new SRectF(35f, 100f, 590f, 200f, -0.5f), CTheme.ThemeColors.Player[0]);
|
|
NoteLines[1] = SingNotes[SingBars].AddPlayer(new SRectF(35f, 350f, 590f, 200f, -0.5f), CTheme.ThemeColors.Player[1]);
|
|
NoteLines[2] = SingNotes[SingBars].AddPlayer(new SRectF(640f, 100f, 590f, 200f, -0.5f), CTheme.ThemeColors.Player[2]);
|
|
NoteLines[3] = SingNotes[SingBars].AddPlayer(new SRectF(640f, 350f, 590f, 200f, -0.5f), CTheme.ThemeColors.Player[3]);
|
|
break;
|
|
*/
|
|
_TimerSongText.Stop();
|
|
_TimerSongText.Reset();
|
|
_TimerDuetText1.Stop();
|
|
_TimerDuetText1.Reset();
|
|
_TimerDuetText2.Stop();
|
|
_TimerDuetText2.Reset();
|
|
|
|
if (song.Notes.Lines.Length != 2)
|
|
_TimerSongText.Start();
|
|
|
|
_StartSong();
|
|
}
|
|
|
|
private void _SetDuetLyricsVisibility(bool isDuet)
|
|
{
|
|
_Statics[_StaticLyricsDuet].Visible = isDuet;
|
|
_Lyrics[_LyricMainDuet].Visible = isDuet;
|
|
_Lyrics[_LyricSubDuet].Visible = isDuet;
|
|
|
|
if (isDuet)
|
|
{
|
|
_Lyrics[_LyricMainTop].Visible = false;
|
|
_Lyrics[_LyricSubTop].Visible = false;
|
|
_Statics[_StaticLyricsTop].Visible = false;
|
|
}
|
|
else
|
|
{
|
|
bool lyricsOnTop = (CGame.NumPlayer != 1) && CConfig.LyricsOnTop == EOffOn.TR_CONFIG_ON;
|
|
_Lyrics[_LyricMainTop].Visible = lyricsOnTop;
|
|
_Lyrics[_LyricSubTop].Visible = lyricsOnTop;
|
|
_Statics[_StaticLyricsTop].Visible = lyricsOnTop;
|
|
}
|
|
}
|
|
|
|
private void _StartSong()
|
|
{
|
|
_PrepareTimeLine();
|
|
CSound.Play(_CurrentStream);
|
|
CSound.RecordStart();
|
|
if (_Webcam)
|
|
CWebcam.Start();
|
|
}
|
|
|
|
private void _Stop()
|
|
{
|
|
//Need this to set other songs to points-var
|
|
while (!CGame.IsFinished())
|
|
CGame.NextRound();
|
|
|
|
_FinishedSinging();
|
|
}
|
|
|
|
private void _FinishedSinging()
|
|
{
|
|
_FadeOut = true;
|
|
CParty.FinishedSinging();
|
|
|
|
if (_Webcam)
|
|
CWebcam.Close();
|
|
}
|
|
|
|
private int _FindCurrentLine(CLines lines, CLine[] line, CSong song)
|
|
{
|
|
float currentTime = _CurrentTime - song.Gap;
|
|
//We are only interested in the last matching line, so either do not check further after line[j].StartBeat > _CurrentBeat or go backwards!
|
|
int j = lines.FindPreviousLine(_CurrentBeat);
|
|
for (; j >= 0; j--)
|
|
{
|
|
float firstNoteTime = CGame.GetTimeFromBeats(line[j].FirstNoteBeat, song.BPM);
|
|
//Earlist possible line break is 10s before first note
|
|
if (firstNoteTime <= currentTime + 10f)
|
|
{
|
|
//First line has no predecessor or line has to be shown
|
|
if (j == 0 || firstNoteTime - CConfig.MinLineBreakTime <= currentTime)
|
|
return j;
|
|
float lastNoteTime = CGame.GetTimeFromBeats(line[j - 1].LastNoteBeat, song.BPM);
|
|
//No line break if last line is not fully evaluated (with 50% tolerance -> tested so notes are drawn)
|
|
if (lastNoteTime + CConfig.MicDelay / 1000f * 1.5f >= currentTime)
|
|
return j - 1;
|
|
return j;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
private void _UpdateLyrics()
|
|
{
|
|
if (_FadeOut)
|
|
return;
|
|
|
|
CSong song = CGame.GetSong();
|
|
|
|
if (song == null)
|
|
return;
|
|
|
|
|
|
_CurrentBeat = CGame.CurrentBeat;
|
|
for (int i = 0; i < song.Notes.LinesCount; i++)
|
|
{
|
|
if (i > 1)
|
|
break; // for later
|
|
|
|
CLines lines = song.Notes.GetLines(i);
|
|
CLine[] line = lines.Line;
|
|
|
|
// find current line
|
|
int nr = _FindCurrentLine(lines, line, song);
|
|
|
|
if (nr != -1)
|
|
{
|
|
for (int j = 0; j < CGame.NumPlayer; j++)
|
|
{
|
|
if (CGame.Player[j].LineNr == i)
|
|
_SingNotes[_SingBars].AddLine(_NoteLines[j], line, nr, j);
|
|
}
|
|
|
|
if (i == 0 && !song.IsDuet || i == 1 && song.IsDuet)
|
|
{
|
|
_Lyrics[_LyricMain].SetLine(line[nr]);
|
|
_Lyrics[_LyricMainTop].SetLine(line[nr]);
|
|
_TimeToFirstNote = CGame.GetTimeFromBeats(line[nr].FirstNoteBeat - line[nr].StartBeat, song.BPM);
|
|
_RemainingTimeToFirstNote = CGame.GetTimeFromBeats(line[nr].FirstNoteBeat - CGame.GetBeatFromTime(_CurrentTime, song.BPM, song.Gap), song.BPM);
|
|
|
|
if (line.Length >= nr + 2)
|
|
{
|
|
_Lyrics[_LyricSub].SetLine(line[nr + 1]);
|
|
_Lyrics[_LyricSubTop].SetLine(line[nr + 1]);
|
|
}
|
|
else
|
|
{
|
|
_Lyrics[_LyricSub].Clear();
|
|
_Lyrics[_LyricSubTop].Clear();
|
|
}
|
|
}
|
|
if (i == 0 && song.IsDuet)
|
|
{
|
|
_Lyrics[_LyricMainDuet].SetLine(line[nr]);
|
|
_TimeToFirstNoteDuet = CGame.GetTimeFromBeats(line[nr].FirstNoteBeat - line[nr].StartBeat, song.BPM);
|
|
_RemainingTimeToFirstNoteDuet = CGame.GetTimeFromBeats(line[nr].FirstNoteBeat - CGame.GetBeatFromTime(_CurrentTime, song.BPM, song.Gap), song.BPM);
|
|
|
|
if (line.Length >= nr + 2)
|
|
_Lyrics[_LyricSubDuet].SetLine(line[nr + 1]);
|
|
else
|
|
_Lyrics[_LyricSubDuet].Clear();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (i == 0 && !song.IsDuet || i == 1 && song.IsDuet)
|
|
{
|
|
_Lyrics[_LyricMain].Clear();
|
|
_Lyrics[_LyricSub].Clear();
|
|
_Lyrics[_LyricMainTop].Clear();
|
|
_Lyrics[_LyricSubTop].Clear();
|
|
_TimeToFirstNote = 0f;
|
|
}
|
|
|
|
if (i == 0 && song.IsDuet)
|
|
{
|
|
_Lyrics[_LyricMainDuet].Clear();
|
|
_Lyrics[_LyricSubDuet].Clear();
|
|
_TimeToFirstNoteDuet = 0f;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void _TogglePause()
|
|
{
|
|
_Pause = !_Pause;
|
|
if (_Pause)
|
|
{
|
|
_Buttons[_ButtonCancel].Visible = true;
|
|
_Buttons[_ButtonContinue].Visible = true;
|
|
if (CGame.NumRounds > CGame.RoundNr && CGame.NumRounds > 1)
|
|
_Buttons[_ButtonSkip].Visible = true;
|
|
else
|
|
_Buttons[_ButtonSkip].Visible = false;
|
|
CSound.Pause(_CurrentStream);
|
|
}
|
|
else
|
|
{
|
|
_Buttons[_ButtonCancel].Visible = false;
|
|
_Buttons[_ButtonContinue].Visible = false;
|
|
_Buttons[_ButtonSkip].Visible = false;
|
|
CSound.Play(_CurrentStream);
|
|
CWebcam.Start();
|
|
}
|
|
}
|
|
|
|
private void _BuildTextStrings(ref List<string> texts)
|
|
{
|
|
_TextScores = new string[CSettings.MaxNumPlayer,CSettings.MaxNumPlayer];
|
|
_TextNames = new string[CSettings.MaxNumPlayer,CSettings.MaxNumPlayer];
|
|
|
|
for (int numplayer = 0; numplayer < CSettings.MaxNumPlayer; numplayer++)
|
|
{
|
|
for (int player = 0; player < CSettings.MaxNumPlayer; player++)
|
|
{
|
|
if (player <= numplayer)
|
|
{
|
|
string target = "P" + (player + 1) + "N" + (numplayer + 1);
|
|
_TextScores[player, numplayer] = "TextScore" + target;
|
|
_TextNames[player, numplayer] = "TextName" + target;
|
|
|
|
texts.Add(_TextScores[player, numplayer]);
|
|
texts.Add(_TextNames[player, numplayer]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void _BuildStaticStrings(ref List<string> statics)
|
|
{
|
|
_StaticScores = new string[CSettings.MaxNumPlayer,CSettings.MaxNumPlayer];
|
|
_StaticAvatars = new string[CSettings.MaxNumPlayer,CSettings.MaxNumPlayer];
|
|
|
|
for (int numplayer = 0; numplayer < CSettings.MaxNumPlayer; numplayer++)
|
|
{
|
|
for (int player = 0; player < CSettings.MaxNumPlayer; player++)
|
|
{
|
|
if (player <= numplayer)
|
|
{
|
|
string target = "P" + (player + 1) + "N" + (numplayer + 1);
|
|
_StaticScores[player, numplayer] = "StaticScore" + target;
|
|
_StaticAvatars[player, numplayer] = "StaticAvatar" + target;
|
|
|
|
statics.Add(_StaticScores[player, numplayer]);
|
|
statics.Add(_StaticAvatars[player, numplayer]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void _SetVisibility()
|
|
{
|
|
_Statics[_StaticLyricsDuet].Visible = false;
|
|
_Statics[_StaticLyricHelper].Visible = false;
|
|
_Statics[_StaticLyricHelperDuet].Visible = false;
|
|
_Statics[_StaticLyricHelperTop].Visible = false;
|
|
_Lyrics[_LyricMainDuet].Visible = false;
|
|
_Lyrics[_LyricSubDuet].Visible = false;
|
|
|
|
_Statics[_StaticSongText].Visible = false;
|
|
_Texts[_TextSongName].Visible = false;
|
|
_Texts[_TextDuetName1].Visible = false;
|
|
_Texts[_TextDuetName2].Visible = false;
|
|
|
|
for (int numplayer = 0; numplayer < CSettings.MaxNumPlayer; numplayer++)
|
|
{
|
|
for (int player = 0; player < CSettings.MaxNumPlayer; player++)
|
|
{
|
|
if (player <= numplayer)
|
|
{
|
|
_Texts[_TextScores[player, numplayer]].Visible = numplayer + 1 == CGame.NumPlayer;
|
|
_Texts[_TextNames[player, numplayer]].Visible = (numplayer + 1 == CGame.NumPlayer)
|
|
&&
|
|
(CConfig.PlayerInfo == EPlayerInfo.TR_CONFIG_PLAYERINFO_BOTH ||
|
|
CConfig.PlayerInfo == EPlayerInfo.TR_CONFIG_PLAYERINFO_NAME);
|
|
_Statics[_StaticScores[player, numplayer]].Visible = numplayer + 1 == CGame.NumPlayer;
|
|
_Statics[_StaticAvatars[player, numplayer]].Visible = (numplayer + 1 == CGame.NumPlayer)
|
|
&&
|
|
(CConfig.PlayerInfo == EPlayerInfo.TR_CONFIG_PLAYERINFO_BOTH ||
|
|
CConfig.PlayerInfo == EPlayerInfo.TR_CONFIG_PLAYERINFO_AVATAR);
|
|
}
|
|
}
|
|
}
|
|
|
|
_Lyrics[_LyricMain].Alpha = 0f;
|
|
_Lyrics[_LyricSub].Alpha = 0f;
|
|
|
|
_Lyrics[_LyricMainTop].Alpha = 0f;
|
|
_Lyrics[_LyricSubTop].Alpha = 0f;
|
|
|
|
_Statics[_StaticLyrics].Alpha = 0f;
|
|
_Statics[_StaticLyricsTop].Alpha = 0f;
|
|
|
|
_Statics[_StaticLyricHelper].Alpha = 0f;
|
|
_Statics[_StaticLyricHelperTop].Alpha = 0f;
|
|
|
|
_Lyrics[_LyricMainDuet].Alpha = 0f;
|
|
_Lyrics[_LyricSubDuet].Alpha = 0f;
|
|
|
|
_Statics[_StaticLyricsDuet].Alpha = 0f;
|
|
_Statics[_StaticLyricHelperDuet].Alpha = 0f;
|
|
}
|
|
|
|
private void _DrawLyricHelper()
|
|
{
|
|
if (_FadeOut)
|
|
return;
|
|
|
|
if (!CSound.IsPlaying(_CurrentStream) && !CSound.IsPaused(_CurrentStream))
|
|
return;
|
|
|
|
CSong song = CGame.GetSong();
|
|
|
|
if (song == null)
|
|
return;
|
|
|
|
float alpha = (float)((Math.Cos(_CurrentTime * Math.PI * 2) + 1) / 2.0) / 2f + 0.5f;
|
|
|
|
if (_TimeToFirstNote > CSettings.LyricHelperMinTime && _RemainingTimeToFirstNote > 0f && _RemainingTimeToFirstNote < CSettings.LyricHelperEnableTime)
|
|
{
|
|
float time = _RemainingTimeToFirstNote;
|
|
float totaltime = CSettings.LyricHelperMoveTime;
|
|
|
|
if (totaltime > _TimeToFirstNote)
|
|
totaltime = _TimeToFirstNote;
|
|
|
|
if (time > totaltime)
|
|
time = totaltime;
|
|
|
|
SRectF rect = _Statics[_StaticLyricHelper].Rect;
|
|
SColorF color = new SColorF(
|
|
_Statics[_StaticLyricHelper].Color.R,
|
|
_Statics[_StaticLyricHelper].Color.G,
|
|
_Statics[_StaticLyricHelper].Color.B,
|
|
_Statics[_StaticLyricHelper].Color.A * _Statics[_StaticLyricHelper].Alpha * alpha);
|
|
|
|
float distance = _Lyrics[_LyricMain].GetCurrentLyricPosX() - rect.X - rect.W;
|
|
CDraw.DrawTexture(_Statics[_StaticLyricHelper].Texture,
|
|
new SRectF(rect.X + distance * (1f - time / totaltime), rect.Y, rect.W, rect.H, rect.Z), color);
|
|
|
|
if (_Statics[_StaticLyricsTop].Visible)
|
|
{
|
|
rect = _Statics[_StaticLyricHelperTop].Rect;
|
|
color = new SColorF(
|
|
_Statics[_StaticLyricHelperTop].Color.R,
|
|
_Statics[_StaticLyricHelperTop].Color.G,
|
|
_Statics[_StaticLyricHelperTop].Color.B,
|
|
_Statics[_StaticLyricHelperTop].Color.A * _Statics[_StaticLyricHelper].Alpha * alpha);
|
|
|
|
distance = _Lyrics[_LyricMainTop].GetCurrentLyricPosX() - rect.X - rect.W;
|
|
CDraw.DrawTexture(_Statics[_StaticLyricHelperTop].Texture,
|
|
new SRectF(rect.X + distance * (1f - time / totaltime), rect.Y, rect.W, rect.H, rect.Z), color);
|
|
}
|
|
}
|
|
|
|
if (song.IsDuet)
|
|
{
|
|
if (_TimeToFirstNoteDuet > CSettings.LyricHelperMinTime && _RemainingTimeToFirstNoteDuet > 0f && _RemainingTimeToFirstNoteDuet < CSettings.LyricHelperEnableTime)
|
|
{
|
|
float time = _RemainingTimeToFirstNoteDuet;
|
|
float totaltime = CSettings.LyricHelperMoveTime;
|
|
|
|
if (totaltime > _TimeToFirstNoteDuet)
|
|
totaltime = _TimeToFirstNoteDuet;
|
|
|
|
if (time > totaltime)
|
|
time = totaltime;
|
|
|
|
SRectF rect = _Statics[_StaticLyricHelperDuet].Rect;
|
|
|
|
SColorF color = new SColorF(
|
|
_Statics[_StaticLyricHelperDuet].Color.R,
|
|
_Statics[_StaticLyricHelperDuet].Color.G,
|
|
_Statics[_StaticLyricHelperDuet].Color.B,
|
|
_Statics[_StaticLyricHelperDuet].Color.A * _Statics[_StaticLyricHelperDuet].Alpha * alpha);
|
|
|
|
float distance = _Lyrics[_LyricMainDuet].GetCurrentLyricPosX() - rect.X - rect.W;
|
|
CDraw.DrawTexture(_Statics[_StaticLyricHelperDuet].Texture,
|
|
new SRectF(rect.X + distance * (1f - time / totaltime), rect.Y, rect.W, rect.H, rect.Z),
|
|
color);
|
|
}
|
|
}
|
|
}
|
|
|
|
private float[] _CalcFadingAlpha()
|
|
{
|
|
float dt = 4f;
|
|
float rt = dt * 0.8f;
|
|
|
|
CSong song = CGame.GetSong();
|
|
if (song == null)
|
|
return null;
|
|
else if (!song.NotesLoaded)
|
|
return null;
|
|
|
|
float[] alpha = new float[song.Notes.Lines.Length * 2];
|
|
float currentTime = _CurrentTime - song.Gap;
|
|
|
|
for (int i = 0; i < song.Notes.LinesCount; i++)
|
|
{
|
|
CLines lines = song.Notes.GetLines(i);
|
|
CLine[] line = lines.Line;
|
|
|
|
// find current line for lyric sub fading
|
|
int currentLineSub = _FindCurrentLine(lines, line, song);
|
|
|
|
// find current line for lyric main fading
|
|
int currentLine = 0;
|
|
for (int j = 0; j < line.Length; j++)
|
|
{
|
|
if (line[j].FirstNoteBeat <= _CurrentBeat)
|
|
currentLine = j;
|
|
}
|
|
|
|
// default values
|
|
alpha[i * 2] = 1f;
|
|
alpha[i * 2 + 1] = 1f;
|
|
|
|
// main line alpha
|
|
if (currentLine == 0 && currentTime < CGame.GetTimeFromBeats(line[currentLine].FirstNoteBeat, song.BPM))
|
|
{
|
|
// first main line and fist note is not reached
|
|
// => fade in
|
|
float diff = CGame.GetTimeFromBeats(line[currentLine].FirstNoteBeat, song.BPM) - currentTime;
|
|
if (diff > dt)
|
|
alpha[i * 2] = 1f - (diff - dt) / rt;
|
|
}
|
|
else if (currentLine < line.Length - 1 && CGame.GetTimeFromBeats(line[currentLine].LastNoteBeat, song.BPM) < currentTime &&
|
|
CGame.GetTimeFromBeats(line[currentLine + 1].FirstNoteBeat, song.BPM) > currentTime)
|
|
{
|
|
// current position is between two lines
|
|
|
|
// time between the to lines
|
|
float diff = CGame.GetTimeFromBeats(line[currentLine + 1].FirstNoteBeat, song.BPM) -
|
|
CGame.GetTimeFromBeats(line[currentLine].LastNoteBeat, song.BPM);
|
|
|
|
// fade only if there is enough time for fading
|
|
if (diff > 3.3f * dt)
|
|
{
|
|
// time elapsed since last line
|
|
float last = currentTime - CGame.GetTimeFromBeats(line[currentLine].LastNoteBeat, song.BPM);
|
|
|
|
// time to next line
|
|
float next = CGame.GetTimeFromBeats(line[currentLine + 1].FirstNoteBeat, song.BPM) - currentTime;
|
|
|
|
if (last < next)
|
|
{
|
|
// fade out
|
|
alpha[i * 2] = 1f - last / rt;
|
|
}
|
|
else
|
|
{
|
|
// fade in if it is time for
|
|
if (next > dt)
|
|
alpha[i * 2] = 1f - (next - dt) / rt;
|
|
}
|
|
}
|
|
}
|
|
else if (currentLine == line.Length - 1 && CGame.GetTimeFromBeats(line[currentLine].LastNoteBeat, song.BPM) < currentTime)
|
|
{
|
|
// last main line and last note was reached
|
|
// => fade out
|
|
float diff = currentTime - CGame.GetTimeFromBeats(line[currentLine].LastNoteBeat, song.BPM);
|
|
alpha[i * 2] = 1f - diff / rt;
|
|
}
|
|
|
|
// sub
|
|
if (currentLineSub < line.Length - 2)
|
|
{
|
|
float diff = CGame.GetTimeFromBeats(line[currentLineSub + 1].FirstNoteBeat, song.BPM) - currentTime;
|
|
|
|
if (diff > dt)
|
|
alpha[i * 2 + 1] = 1f - (diff - dt) / rt;
|
|
}
|
|
|
|
if (alpha[i * 2] < 0f)
|
|
alpha[i * 2] = 0f;
|
|
|
|
if (alpha[i * 2 + 1] < 0f)
|
|
alpha[i * 2 + 1] = 0f;
|
|
}
|
|
|
|
return alpha;
|
|
}
|
|
|
|
private void _UpdateSongText()
|
|
{
|
|
if (_TimerSongText.IsRunning && !_Lyrics[_LyricMainDuet].Visible && !_Lyrics[_LyricMainTop].Visible)
|
|
{
|
|
float t = _TimerSongText.ElapsedMilliseconds / 1000f;
|
|
if (t < 10f)
|
|
{
|
|
_Statics[_StaticSongText].Visible = true;
|
|
_Texts[_TextSongName].Visible = true;
|
|
|
|
if (t < 7f)
|
|
{
|
|
_Statics[_StaticSongText].Color.A = 1f;
|
|
_Texts[_TextSongName].Color.A = 1f;
|
|
}
|
|
else
|
|
{
|
|
_Statics[_StaticSongText].Color.A = (3f - (t - 7f)) / 3f;
|
|
_Texts[_TextSongName].Color.A = (3f - (t - 7f)) / 3f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_Statics[_StaticSongText].Visible = false;
|
|
_Texts[_TextSongName].Visible = false;
|
|
_TimerSongText.Stop();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_Statics[_StaticSongText].Visible = false;
|
|
_Texts[_TextSongName].Visible = false;
|
|
}
|
|
}
|
|
|
|
private void _UpdateDuetText()
|
|
{
|
|
if (CGame.GetSong() != null)
|
|
{
|
|
//Timer for first duet-part
|
|
if (_TimerDuetText1.IsRunning)
|
|
{
|
|
float t = _TimerDuetText1.ElapsedMilliseconds / 1000f;
|
|
if (t < 10f)
|
|
{
|
|
_Texts[_TextDuetName1].Visible = true;
|
|
|
|
if (t < 3f)
|
|
_Texts[_TextDuetName1].Color.A = (3f - (3f - t)) / 3f;
|
|
else if (t < 7f)
|
|
_Texts[_TextDuetName1].Color.A = 1f;
|
|
else
|
|
_Texts[_TextDuetName1].Color.A = (3f - (t - 7f)) / 3f;
|
|
}
|
|
else
|
|
{
|
|
_Texts[_TextDuetName1].Visible = false;
|
|
_TimerDuetText1.Stop();
|
|
}
|
|
}
|
|
else if (!_TimerDuetText1.IsRunning && _TimerDuetText1.ElapsedMilliseconds == 0 && _Lyrics[_LyricMainDuet].Alpha > 0 && CGame.GetSong().IsDuet)
|
|
_TimerDuetText1.Start();
|
|
else
|
|
_Texts[_TextDuetName1].Visible = false;
|
|
//Timer for second duet-part
|
|
if (_TimerDuetText2.IsRunning)
|
|
{
|
|
float t = _TimerDuetText2.ElapsedMilliseconds / 1000f;
|
|
if (t < 10f)
|
|
{
|
|
_Texts[_TextDuetName2].Visible = true;
|
|
|
|
if (t < 3f)
|
|
_Texts[_TextDuetName2].Color.A = (3f - (3f - t)) / 3f;
|
|
else if (t < 7f)
|
|
_Texts[_TextDuetName2].Color.A = 1f;
|
|
else
|
|
_Texts[_TextDuetName2].Color.A = (3f - (t - 7f)) / 3f;
|
|
}
|
|
else
|
|
{
|
|
_Texts[_TextDuetName2].Visible = false;
|
|
_TimerDuetText2.Stop();
|
|
}
|
|
}
|
|
else if (!_TimerDuetText2.IsRunning && _TimerDuetText2.ElapsedMilliseconds == 0 && _Lyrics[_LyricMain].Alpha > 0 && CGame.GetSong().IsDuet)
|
|
_TimerDuetText2.Start();
|
|
else
|
|
_Texts[_TextDuetName2].Visible = false;
|
|
}
|
|
}
|
|
|
|
private void _UpdateTimeLine()
|
|
{
|
|
CSong song = CGame.GetSong();
|
|
|
|
if (song == null)
|
|
return;
|
|
|
|
float totalTime = CSound.GetLength(_CurrentStream);
|
|
if (Math.Abs(song.Finish) > 0.001)
|
|
totalTime = song.Finish;
|
|
|
|
float remainingTime = totalTime - _CurrentTime;
|
|
totalTime -= song.Start;
|
|
float currentTime = _CurrentTime - song.Start;
|
|
|
|
if (totalTime <= 0f)
|
|
return;
|
|
|
|
switch (CConfig.TimerMode)
|
|
{
|
|
case ETimerMode.TR_CONFIG_TIMERMODE_CURRENT:
|
|
int min = (int)Math.Floor(currentTime / 60f);
|
|
int sec = (int)(currentTime - min * 60f);
|
|
_Texts[_TextTime].Text = min.ToString("00") + ":" + sec.ToString("00");
|
|
break;
|
|
|
|
case ETimerMode.TR_CONFIG_TIMERMODE_REMAINING:
|
|
min = (int)Math.Floor(remainingTime / 60f);
|
|
sec = (int)(remainingTime - min * 60f);
|
|
_Texts[_TextTime].Text = "-" + min.ToString("00") + ":" + sec.ToString("00");
|
|
break;
|
|
|
|
case ETimerMode.TR_CONFIG_TIMERMODE_TOTAL:
|
|
min = (int)Math.Floor(totalTime / 60f);
|
|
sec = (int)(totalTime - min * 60f);
|
|
_Texts[_TextTime].Text = "#" + min.ToString("00") + ":" + sec.ToString("00");
|
|
break;
|
|
}
|
|
|
|
|
|
switch (CConfig.TimerLook)
|
|
{
|
|
case ETimerLook.TR_CONFIG_TIMERLOOK_NORMAL:
|
|
_TimeLineRect.W = _Statics[_StaticTimeLine].Rect.W * (currentTime / totalTime);
|
|
break;
|
|
|
|
case ETimerLook.TR_CONFIG_TIMERLOOK_EXPANDED:
|
|
CStatic stat = _Statics[_StaticTimeLine];
|
|
int currentBeat = CGame.CurrentBeat;
|
|
for (int i = 0; i < _TimeRects.Count; i++)
|
|
{
|
|
if (currentBeat >= _TimeRects[i].StartBeat && currentBeat <= _TimeRects[i].EndBeat)
|
|
{
|
|
_TimeRects[i].Rect.Texture = _Statics[_StaticTimeLineExpandedHighlighted].Texture;
|
|
_TimeRects[i].Rect.Color = _Statics[_StaticTimeLineExpandedHighlighted].Color;
|
|
}
|
|
else
|
|
{
|
|
_TimeRects[i].Rect.Texture = _Statics[_StaticTimeLineExpandedNormal].Texture;
|
|
_TimeRects[i].Rect.Color = _Statics[_StaticTimeLineExpandedNormal].Color;
|
|
}
|
|
}
|
|
_Statics[_StaticTimePointer].Rect.X = stat.Rect.X + stat.Rect.W * (currentTime / totalTime);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void _PrepareTimeLine()
|
|
{
|
|
CStatic stat = _Statics[_StaticTimeLine];
|
|
switch (CConfig.TimerLook)
|
|
{
|
|
case ETimerLook.TR_CONFIG_TIMERLOOK_NORMAL:
|
|
_TimeLineRect = new SRectF(stat.Rect.X, stat.Rect.Y, 0f, stat.Rect.H, stat.Rect.Z);
|
|
_Statics[_StaticTimePointer].Visible = false;
|
|
break;
|
|
|
|
case ETimerLook.TR_CONFIG_TIMERLOOK_EXPANDED:
|
|
_TimeRects.Clear();
|
|
_Statics[_StaticTimePointer].Visible = true;
|
|
|
|
CSong song = CGame.GetSong();
|
|
|
|
if (song == null)
|
|
return;
|
|
|
|
float totalTime = CSound.GetLength(_CurrentStream);
|
|
if (Math.Abs(song.Finish) > 0.001)
|
|
totalTime = song.Finish;
|
|
|
|
totalTime -= song.Start;
|
|
|
|
if (totalTime <= 0f)
|
|
return;
|
|
|
|
CLines[] partLines = song.Notes.Lines;
|
|
foreach (CLines partLine in partLines)
|
|
{
|
|
CLine[] line = partLine.Line;
|
|
for (int j = 0; j < line.Length; j++)
|
|
{
|
|
if (line[j].VisibleInTimeLine)
|
|
{
|
|
STimeRect trect = new STimeRect {StartBeat = line[j].FirstNoteBeat, EndBeat = line[j].EndBeat};
|
|
trect.Rect = GetNewStatic(new STexture(-1),
|
|
new SColorF(1f, 1f, 1f, 1f),
|
|
new SRectF(
|
|
stat.Rect.X + stat.Rect.W * ((CGame.GetTimeFromBeats(trect.StartBeat, song.BPM) + song.Gap - song.Start) / totalTime),
|
|
stat.Rect.Y,
|
|
stat.Rect.W * (CGame.GetTimeFromBeats(trect.EndBeat - trect.StartBeat, song.BPM) / totalTime),
|
|
stat.Rect.H,
|
|
stat.Rect.Z));
|
|
|
|
_TimeRects.Add(trect);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void _UpdateAvatars()
|
|
{
|
|
for (int i = 0; i < CGame.NumPlayer; i++)
|
|
{
|
|
if (CGame.Player[i].ProfileID > -1 && CProfiles.NumProfiles > CGame.Player[i].ProfileID)
|
|
_Statics[_StaticAvatars[i, CGame.NumPlayer - 1]].Texture = CProfiles.Profiles[CGame.Player[i].ProfileID].Avatar.Texture;
|
|
else
|
|
_Statics[_StaticAvatars[i, CGame.NumPlayer - 1]].Visible = false;
|
|
}
|
|
}
|
|
|
|
private void _UpdateNames()
|
|
{
|
|
for (int i = 0; i < CGame.NumPlayer; i++)
|
|
{
|
|
if (CGame.Player[i].ProfileID > -1 && CProfiles.NumProfiles > CGame.Player[i].ProfileID)
|
|
_Texts[_TextNames[i, CGame.NumPlayer - 1]].Text = CProfiles.Profiles[CGame.Player[i].ProfileID].PlayerName;
|
|
else
|
|
_Texts[_TextNames[i, CGame.NumPlayer - 1]].Visible = false;
|
|
}
|
|
}
|
|
}
|
|
} |