|
From: Tapio V. <aa...@us...> - 2009-10-28 20:39:28
|
Module: performous
Branch: master
Commit: 4c72ef20e159068c294a06bc7b558ca5da800d44
Author: Tapio Vierros <tap...@gm...>
Date: Wed Oct 28 22:35:50 2009 +0200
Fixed a couple of bugs in singer textual feedback.
Now the first lyrics row is also evaluated correctly and the text is updated even if there is no singing.
---
game/layout_singer.cc | 4 ++--
game/player.cc | 41 +++++++++++++++++++++++++----------------
game/player.hh | 9 ++++++---
3 files changed, 33 insertions(+), 21 deletions(-)
diff --git a/game/layout_singer.cc b/game/layout_singer.cc
index e99c79b..97fcc50 100644
--- a/game/layout_singer.cc
+++ b/game/layout_singer.cc
@@ -53,8 +53,8 @@ void LayoutSinger::drawScore(Position position) {
break;
}
m_score_text[i%4]->draw();
- // Give some feedback on how well the last lyricss row went
- if (p->m_maxLineScore > 0) {
+ // Give some feedback on how well the last lyrics row went
+ if (p->m_prevLineScore >= 0) {
std::string prevLineRank;
if (p->m_prevLineScore > 0.9) { prevLineRank = "Perfect"; glColor4f(0.5, 1.0, 0.0, act); }
else if (p->m_prevLineScore > 0.8) { prevLineRank = "Excellent"; glColor4f(0.2, 0.8, 0.2, act); }
diff --git a/game/player.cc b/game/player.cc
index 02df7d9..fa3a751 100644
--- a/game/player.cc
+++ b/game/player.cc
@@ -4,35 +4,44 @@
void Player::update() {
if (m_pos == m_pitch.size()) return; // End of song already
+ double beginTime = Engine::TIMESTEP * m_pos;
Tone const* t = m_analyzer.findTone();
if (t) {
m_activitytimer = 1000;
- double beginTime = Engine::TIMESTEP * m_pos;
m_pitch[m_pos++] = std::make_pair(t->freq, t->stabledb);
- double endTime = Engine::TIMESTEP * m_pos;
- while (m_scoreIt != m_song.notes.end()) {
+ } else {
+ if (m_activitytimer > 0) --m_activitytimer;
+ m_pitch[m_pos++] = std::make_pair(getNaN(), -getInf());
+ }
+ double endTime = Engine::TIMESTEP * m_pos;
+ while (m_scoreIt != m_song.notes.end()) {
+ if (t) {
+ // Add score
double score_addition = m_song.m_scoreFactor * m_scoreIt->score(m_song.scale.getNote(t->freq), beginTime, endTime);
m_score += score_addition;
m_lineScore += score_addition;
- // If a row of lyrics ends, calculate how well it went
- if (m_scoreIt->type == Note::SLEEP && m_lineScore > 0) {
+ }
+ // If a row of lyrics ends, calculate how well it went
+ if (m_scoreIt->type == Note::SLEEP) {
+ if (m_maxLineScore == 0) { // Has the maximum already been calculated for this SLEEP?
m_prevLineScore = m_lineScore;
- if (m_maxLineScore > 0) m_prevLineScore /= m_maxLineScore;
- m_lineScore = 0;
- m_maxLineScore = 0;
- Notes::const_iterator maxScoreIt = m_scoreIt + 1;
- while (maxScoreIt != m_song.notes.end() && maxScoreIt->type != Note::SLEEP) {
+ // Calculate max score of the completed row
+ Notes::const_reverse_iterator maxScoreIt(m_scoreIt);
+ while (maxScoreIt != m_song.notes.rend() && maxScoreIt->type != Note::SLEEP) {
m_maxLineScore += m_song.m_scoreFactor * maxScoreIt->maxScore();
maxScoreIt++;
}
+ if (m_maxLineScore > 0)
+ m_prevLineScore /= m_maxLineScore;
+ else m_prevLineScore = -1;
+ m_lineScore = 0;
}
- if (endTime < m_scoreIt->end) break;
- ++m_scoreIt;
+ } else {
+ m_maxLineScore = 0; // Not in SLEEP note anymore, so reset maximum
}
- m_score = clamp(m_score, 0.0, 1.0);
- } else {
- if (m_activitytimer > 0) --m_activitytimer;
- m_pitch[m_pos++] = std::make_pair(getNaN(), -getInf());
+ if (endTime < m_scoreIt->end) break;
+ ++m_scoreIt;
}
+ m_score = clamp(m_score, 0.0, 1.0);
}
diff --git a/game/player.hh b/game/player.hh
index 48c2588..340326b 100644
--- a/game/player.hh
+++ b/game/player.hh
@@ -24,16 +24,19 @@ struct Player {
double m_score;
/// score for current line
double m_lineScore;
- /// maximum score for the current line
+ /// maximum score for the previous line
double m_maxLineScore;
- /// score for the previous line (normalized)
+ /// score for the previous line (normalized [0,1])
double m_prevLineScore;
/// activity timer
unsigned m_activitytimer;
/// score iterator
Notes::const_iterator m_scoreIt;
/// constructor
- Player(Song& song, Analyzer& analyzer, size_t frames): m_song(song), m_analyzer(analyzer), m_pitch(frames, std::make_pair(getNaN(), -getInf())), m_pos(), m_score(), m_activitytimer(), m_scoreIt(m_song.notes.begin()) {}
+ Player(Song& song, Analyzer& analyzer, size_t frames):
+ m_song(song), m_analyzer(analyzer), m_pitch(frames, std::make_pair(getNaN(),
+ -getInf())), m_pos(), m_score(), m_lineScore(), m_maxLineScore(), m_prevLineScore(-1),
+ m_activitytimer(), m_scoreIt(m_song.notes.begin()) {}
/// prepares analyzer
void prepare() { m_analyzer.process(); }
/// updates player stats
|