|
From: Lasse Kärkkäi. <tr...@us...> - 2010-06-17 22:40:36
|
Module: performous
Branch: portaudio
Commit: bf2c4bdf7f07a2edf9551502ec7cdec6ea031335
Author: Felix Bertram <fl...@be...>
Date: Mon Jun 7 21:33:29 2010 -0700
Implementation of practice mode (drums only)
- holds game at failed chord
- resumes audio once chord is completed
- to enable: set m_practmode = true in screen_sing.c
---
game/guitargraph.cc | 50 ++++++++++++++++++++++++++++++++++++++++++++------
game/guitargraph.hh | 4 +++-
game/screen_sing.cc | 12 +++++++++---
game/screen_sing.hh | 3 ++-
4 files changed, 58 insertions(+), 11 deletions(-)
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index bc6e929..5a1e122 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -57,7 +57,7 @@ namespace {
inline float blend(float a, float b, float f) { return a*f + b*(1.0f-f); }
}
-GuitarGraph::GuitarGraph(Audio& audio, Song const& song, bool drums, int number):
+GuitarGraph::GuitarGraph(Audio& audio, Song const& song, bool drums, int number, bool practmode):
InstrumentGraph(audio, song, drums ? input::DRUMS : input::GUITAR),
m_button(getThemePath("button.svg")),
m_tail(getThemePath("tail.svg")),
@@ -71,6 +71,7 @@ GuitarGraph::GuitarGraph(Audio& audio, Song const& song, bool drums, int number)
m_drums(drums),
m_use3d(config["graphic/3d_notes"].b()),
m_leftymode(false),
+ m_practmode(practmode),
m_level(),
m_track_index(m_instrumentTracks.end()),
m_dfIt(m_drumfills.end()),
@@ -84,7 +85,8 @@ GuitarGraph::GuitarGraph(Audio& audio, Song const& song, bool drums, int number)
m_drumfillScore(),
m_soloTotal(),
m_soloScore(),
- m_solo()
+ m_solo(),
+ m_practHold(false)
{
// Copy all tracks of supported types (either drums or non-drums) to m_instrumentTracks
for (InstrumentTracks::const_iterator it = m_song.instrumentTracks.begin(); it != m_song.instrumentTracks.end(); ++it) {
@@ -248,10 +250,32 @@ void GuitarGraph::engine() {
}
// Countdown to start
handleCountdown(time, time < getNotesBeginTime() ? getNotesBeginTime() : m_jointime+1);
+
+ // FIXME: this is a band aid to release m_practHold
+ // this may happen in conjunction with the regular pause feature
+ if (m_practHold && !m_audio.isPaused()) m_practHold = false;
+
// Skip missed notes
- while (m_chordIt != m_chords.end() && m_chordIt->begin + maxTolerance < time) {
+ // we hold the note a litle bit *before* they go out of the tolerance window
+ // this is important in order for the hit-detection to still accept the notes
+ // FIXME: need to confirm that this timing is reliable,
+ // if a note gets marked as 'past' completing the chord does not re-start the song
+ double past = time - maxTolerance + (m_practmode ? 0.05 : 0.0);
+ while (!m_practHold && m_chordIt != m_chords.end() && m_chordIt->begin < past) {
if ( (m_drums && m_chordIt->status != m_chordIt->polyphony)
- || (!m_drums && m_chordIt->status == 0) ) endStreak();
+ || (!m_drums && m_chordIt->status == 0) ) {
+ endStreak();
+ if (m_practmode && !dead()) {
+ // in practice mode hold the chord here
+ // m_chordIt must not change until finishing the chord
+ m_audio.seekPos(m_chordIt->begin);
+ m_audio.pause(true);
+ m_practHold = true;
+ endStreak();
+ std::cout << "practice: hold chord at " << m_chordIt->begin << ", status = "<< m_chordIt->status << std::endl;
+ break;
+ }
+ }
// Calculate solo total score
if (m_solo) { m_soloScore += m_chordIt->score; m_soloTotal += m_chordIt->polyphony * points(0);
// Solo just ended?
@@ -264,6 +288,18 @@ void GuitarGraph::engine() {
++m_dead;
++m_chordIt;
}
+
+ // just finished a chord in practice mode
+ if (m_practHold &&
+ ( (m_drums && m_chordIt->status == m_chordIt->polyphony)
+ || (!m_drums && m_chordIt->status != 0) ) ) {
+ // now we have completed the chord
+ // m_chordIt must not change from holding the chord until we get here
+ if (m_audio.isPaused()) m_audio.togglePause();
+ m_practHold = false;
+ std::cout << "practice: finish chord at " << m_chordIt->begin << std::endl;
+ }
+
if (difficulty_changed) m_dead = 0; // if difficulty is changed, m_dead would get incorrect
// Adjust the correctness value
if (!m_events.empty() && m_events.back().type == 0) m_correctness.setTarget(0.0, true);
@@ -451,16 +487,18 @@ void GuitarGraph::drumHit(double time, int fret) {
// in kiddy mode we don't care about the correct pad
// all that matters is that there is still a missing note in that chord
if (m_chordIt->status == m_chordIt->polyphony) continue;
- } else if (m_notes[it->dur[fret]]) continue; // invalid fret/hit or already played
+ } else if ((!it->dur[fret]) || (m_notes[it->dur[fret]])) continue; // invalid fret/hit or already played
double error = std::abs(it->begin - time);
if (error < tolerance) {
best = it;
tolerance = error;
signed_error = it->begin - time;
+ if (m_practHold) break; // during practice hold the chord will always be m_chordIt
}
}
- if (best == m_chords.end()) fail(time, fret); // None found
+ if ((best == m_chords.end())
+ || (m_practHold && best != m_chordIt)) fail(time, fret); // None found
else {
// Skip all chords earlier than the best fit chord
for (; best != m_chordIt; ++m_chordIt) {
diff --git a/game/guitargraph.hh b/game/guitargraph.hh
index 37db183..ed8b931 100644
--- a/game/guitargraph.hh
+++ b/game/guitargraph.hh
@@ -52,7 +52,7 @@ static inline bool operator==(Chord const& a, Chord const& b) {
class GuitarGraph: public InstrumentGraph {
public:
/// constructor
- GuitarGraph(Audio& audio, Song const& song, bool drums, int number);
+ GuitarGraph(Audio& audio, Song const& song, bool drums, int number, bool practmode=false);
/** draws GuitarGraph
* @param time at which time to draw
*/
@@ -97,6 +97,7 @@ class GuitarGraph: public InstrumentGraph {
bool m_drums; /// are we using drums?
bool m_use3d; /// are we using 3d?
bool m_leftymode; /// switch guitar notes to right-to-left direction
+ bool m_practmode; /// switch to enable practice mode
// Track stuff
enum Difficulty {
@@ -148,5 +149,6 @@ class GuitarGraph: public InstrumentGraph {
double m_soloTotal; /// maximum solo score
double m_soloScore; /// score during solo
bool m_solo; /// are we currently playing a solo
+ bool m_practHold; /// true if holding a chord during practice
};
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index 6f62d8b..dd822f3 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -30,6 +30,7 @@ namespace {
}
void ScreenSing::enter() {
+ //m_practmode = true; // un-comment this line to play with practice mode. temporary, of course!
ScreenManager* sm = ScreenManager::getSingletonPtr();
sm->flashMessage(_("Loading song..."), 0.0, 1.0, 0.5);
sm->drawFlashMessage(); sm->window().swap(); // Make loading message show
@@ -97,7 +98,7 @@ void ScreenSing::enter() {
if (type == 3) break;
}
if (type == 0) m_dancers.push_back(new DanceGraph(m_audio, *m_song));
- else m_instruments.push_back(new GuitarGraph(m_audio, *m_song, type == 2, idx));
+ else m_instruments.push_back(new GuitarGraph(m_audio, *m_song, type == 2, idx, m_practmode));
++idx;
} catch (input::NoDevError&) {
++type;
@@ -401,8 +402,13 @@ void ScreenSing::draw() {
}
if (m_audio.isPaused()) {
- m_pause_icon->dimensions.middle().center().fixedWidth(.32);
- m_pause_icon->draw();
+ if (!m_practmode) {
+ m_pause_icon->dimensions.middle().center().fixedWidth(.32);
+ m_pause_icon->draw();
+ } else {
+ // we get here when the song is on hold during practice
+ // TODO: display some (small) info screen here
+ }
}
}
diff --git a/game/screen_sing.hh b/game/screen_sing.hh
index 5ba012d..c743877 100644
--- a/game/screen_sing.hh
+++ b/game/screen_sing.hh
@@ -50,7 +50,7 @@ class ScreenSing: public Screen {
public:
/// constructor
ScreenSing(std::string const& name, Audio& audio, Capture& capture, Database& database, Backgrounds& bgs):
- Screen(name), m_audio(audio), m_capture(capture), m_database(database), m_backgrounds(bgs), m_latencyAV(), m_only_singers_alive(true)
+ Screen(name), m_audio(audio), m_capture(capture), m_database(database), m_backgrounds(bgs), m_latencyAV(), m_only_singers_alive(true), m_practmode(false)
{}
void enter();
void exit();
@@ -92,5 +92,6 @@ class ScreenSing: public Screen {
boost::shared_ptr<ThemeSing> theme;
AnimValue m_quitTimer;
bool m_only_singers_alive;
+ bool m_practmode;
};
|