You can subscribe to this list here.
| 2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(25) |
Jul
(288) |
Aug
(119) |
Sep
(31) |
Oct
(59) |
Nov
(458) |
Dec
(359) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2010 |
Jan
(268) |
Feb
(26) |
Mar
(36) |
Apr
(48) |
May
(119) |
Jun
(37) |
Jul
(173) |
Aug
(429) |
Sep
(137) |
Oct
(156) |
Nov
(59) |
Dec
(45) |
| 2011 |
Jan
(398) |
Feb
(257) |
Mar
(49) |
Apr
(5) |
May
(34) |
Jun
(11) |
Jul
(38) |
Aug
(12) |
Sep
(1) |
Oct
(49) |
Nov
(5) |
Dec
(10) |
| 2012 |
Jan
(21) |
Feb
(32) |
Mar
(20) |
Apr
(1) |
May
(2) |
Jun
|
Jul
(173) |
Aug
|
Sep
(25) |
Oct
(6) |
Nov
(44) |
Dec
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:46:16
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Sat Feb 11 05:52:08 2012 +0200
Cleanup: determine preview times in song parser rather than in song browser.
---
game/screen_songs.cc | 9 ++-------
game/songparser.cc | 2 ++
2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/game/screen_songs.cc b/game/screen_songs.cc
index fc0c86e..bf8fa63 100644
--- a/game/screen_songs.cc
+++ b/game/screen_songs.cc
@@ -178,13 +178,8 @@ void ScreenSongs::stopMultimedia(ScreenSharedInfo& info) {
// Play/stop preview playback (if it is the time)
if (info.music != m_playing && m_playTimer.get() > 0.3) {
m_songbg.reset(); m_video.reset();
- double pstart = 0;
- if (!m_songs.empty() && !m_jukebox) {
- pstart = m_songs.current().preview_start;
- if (pstart != pstart) pstart = 100; // true if NaN, 100 is caught in the next min
- // 5.0s is for performance (don't make it higher unless you implement better seeking method in songs)
- pstart = std::min(pstart, (info.music.size() == 1 ? 30.0 : 5.0)); // we can seek further in 1-track songs
- }
+ double pstart = 0.0; // Playback starting time
+ if (!m_songs.empty() && !m_jukebox) pstart = m_songs.current().preview_start; // In regular mode
if (info.music.empty()) m_audio.fadeout(1.0); else m_audio.playMusic(info.music, true, 2.0, pstart);
if (!info.songbg.empty()) try { m_songbg.reset(new Surface(info.songbg)); } catch (std::exception const&) {}
if (!info.video.empty() && config["graphic/video"].b()) m_video.reset(new Video(info.video, info.videoGap));
diff --git a/game/songparser.cc b/game/songparser.cc
index 7c63d39..d698b15 100644
--- a/game/songparser.cc
+++ b/game/songparser.cc
@@ -85,6 +85,8 @@ SongParser::SongParser(Song& s):
else if (type == INI) iniParseHeader();
else if (type == XML) xmlParseHeader();
else if (type == SM) { smParseHeader(); s.dropNotes(); } // Hack: drop notes here
+ // Default for preview position if none was specified in header
+ if (s.preview_start != s.preview_start) s.preview_start = (type == INI ? 5.0 : 30.0); // 5 s for band mode, 30 s for others
} catch (std::runtime_error& e) {
throw SongParserException(e.what(), m_linenum);
}
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:46:08
|
Author: Tapio Vierros <tap...@gm...> Date: Tue Jan 31 13:39:59 2012 +0200 Configuration_bg.svg not used anymore. --- themes/default/configuration_bg.svg | 480 ----------------------------------- 1 files changed, 0 insertions(+), 480 deletions(-) |
|
From: rainbyte <rai...@us...> - 2012-07-17 10:46:05
|
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 31 13:18:44 2012 +0200
Apparantly boost nowadays prints quotes to paths by itself.
---
game/configuration.cc | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/game/configuration.cc b/game/configuration.cc
index ec747db..1b59858 100644
--- a/game/configuration.cc
+++ b/game/configuration.cc
@@ -283,7 +283,7 @@ void writeConfig(bool system) {
if (exists(conf)) remove(conf);
if (dirty) {
rename(tmp, conf);
- std::cerr << "Saved configuration to \"" << conf << "\"" << std::endl;
+ std::cerr << "Saved configuration to " << conf << std::endl;
} else {
std::cerr << "Using default settings, no configuration file needed." << std::endl;
}
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:45:59
|
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 31 13:14:36 2012 +0200
GUI theme switcher.
* Screen switching is currently needed to apply the new theme
* Uses enum config type
--> So might pick wrong saved theme when they are added or deleted
* Needs more testing
---
data/schema.xml | 7 ++++---
game/cache.cc | 2 +-
game/configuration.cc | 17 +++++++++++++++++
game/configuration.hh | 1 +
game/fs.cc | 31 +++++++++++++++++++++++++++++--
game/fs.hh | 3 +++
6 files changed, 55 insertions(+), 6 deletions(-)
diff --git a/data/schema.xml b/data/schema.xml
index 29b420c..a51b769 100644
--- a/data/schema.xml
+++ b/data/schema.xml
@@ -42,10 +42,11 @@ to save the current settings to XML.
<short>Pitch waves</short>
<long>Enable singing pitch display (when not in karaoke mode).</long>
</entry>
- <entry name="game/theme" type="string">
- <stringvalue>default</stringvalue>
+ <entry name="game/theme" type="int" value="-1">
+ <limits min="-1" max="-1" step="0" />
+ <!-- Enum options added dynamically by scanning theme folders -->
<short>Theme</short>
- <long>Name of the theme to use or absolute path to theme folder.</long>
+ <long>Name of the theme to use.</long>
</entry>
<entry name="game/keyboard_guitar" type="bool" value="true">
<short>Keyboard as guitar</short>
diff --git a/game/cache.cc b/game/cache.cc
index 0f1edd0..5fd637f 100644
--- a/game/cache.cc
+++ b/game/cache.cc
@@ -16,7 +16,7 @@ namespace cache {
#endif
if (isThemeResource(svgfilename)) {
- std::string const theme_name = (config["game/theme"].s().empty() ? "default" : config["game/theme"].s());
+ std::string const theme_name = (config["game/theme"].getEnumName().empty() ? "default" : config["game/theme"].getEnumName());
cache_filename = getCacheDir() / "themes" / theme_name / cache_basename;
} else {
// We use the full path under cache to avoid name collisions
diff --git a/game/configuration.cc b/game/configuration.cc
index de92d67..ec747db 100644
--- a/game/configuration.cc
+++ b/game/configuration.cc
@@ -152,6 +152,12 @@ void ConfigItem::addEnum(std::string name) {
m_step = 1;
}
+std::string ConfigItem::getEnumName() {
+ int val = i();
+ if (val >= 0 && val < m_enums.size()) return m_enums[val];
+ return "";
+}
+
template <typename T> void ConfigItem::updateNumeric(xmlpp::Element& elem, int mode) {
xmlpp::NodeSet ns = elem.find("limits");
if (!ns.empty()) setLimits<T>(dynamic_cast<xmlpp::Element&>(*ns[0]), m_min, m_max, m_step);
@@ -367,4 +373,15 @@ void readConfig() {
readConfigXML(schemafile, 0); // Read schema and defaults
readConfigXML(systemConfFile, 1); // Update defaults with system config
readConfigXML(userConfFile, 2); // Read user settings
+ { // Populate themes
+ ConfigItem& ci = config["game/theme"];
+ std::vector<std::string> themes = getThemes();
+ bool useDefaultTheme = (ci.i() == -1);
+ for (int i = 0; i < themes.size(); ++i) {
+ ci.addEnum(themes[i]);
+ // Select the default theme is no other is selected
+ if (useDefaultTheme && themes[i] == "default")
+ ci.i() = i;
+ }
+ }
}
diff --git a/game/configuration.hh b/game/configuration.hh
index 93278f8..3122ddd 100644
--- a/game/configuration.hh
+++ b/game/configuration.hh
@@ -38,6 +38,7 @@ class ConfigItem {
std::string const& getShortDesc() const { return m_shortDesc; } ///< get the short description for this ConfigItem
std::string const& getLongDesc() const { return m_longDesc; } ///< get the long description for this ConfigItem
void addEnum(std::string name); ///< Dynamically adds an enum to all values
+ std::string getEnumName(); ///< Returns the selected enum option's text
private:
template <typename T> void updateNumeric(xmlpp::Element& elem, int mode); ///< Used internally for loading XML
diff --git a/game/fs.cc b/game/fs.cc
index 545206e..cb59487 100644
--- a/game/fs.cc
+++ b/game/fs.cc
@@ -98,7 +98,7 @@ fs::path getCacheDir() {
}
fs::path getThemeDir() {
- std::string theme = config["game/theme"].s();
+ std::string theme = config["game/theme"].getEnumName();
static const std::string defaultTheme = "default";
if (theme.empty()) theme = defaultTheme;
return getDataDir() / "themes" / theme;
@@ -117,7 +117,7 @@ fs::path pathMangle(fs::path const& dir) {
}
std::string getThemePath(std::string const& filename) {
- std::string theme = config["game/theme"].s();
+ std::string theme = config["game/theme"].getEnumName();
static const std::string defaultTheme = "default";
if (theme.empty()) theme = defaultTheme;
// Try current theme and if that fails, try default theme and finally data dir
@@ -126,6 +126,33 @@ std::string getThemePath(std::string const& filename) {
return getPath(filename);
}
+std::vector<std::string> getThemes() {
+ std::vector<std::string> themes;
+ // Search all paths for themes folders and add them
+ Paths const& paths = getPaths();
+ for (Paths::const_iterator it = paths.begin(); it != paths.end(); ++it) {
+ fs::path p = *it;
+ p /= fs::path("themes");
+ if (fs::is_directory(p)) {
+ // Gather the themes in this folder
+ for (fs::directory_iterator dirIt(p), dirEnd; dirIt != dirEnd; ++dirIt) {
+ fs::path p2 = dirIt->path();
+ if (fs::is_directory(p2)) {
+ #if BOOST_FILESYSTEM_VERSION < 3
+ themes.push_back(p2.leaf());
+ #else
+ themes.push_back(p2.filename().string());
+ #endif
+ }
+ }
+ }
+ }
+ // No duplicates allowed
+ std::sort(themes.begin(), themes.end());
+ std::unique(themes.begin(), themes.end());
+ return themes;
+}
+
bool isThemeResource(fs::path filename){
try {
#if BOOST_FILESYSTEM_VERSION < 3
diff --git a/game/fs.hh b/game/fs.hh
index 2743425..a77265a 100644
--- a/game/fs.hh
+++ b/game/fs.hh
@@ -33,6 +33,9 @@ fs::path pathMangle(fs::path const& dir);
/** Get full path to a file from the current theme **/
std::string getThemePath(std::string const& filename);
+/** Get available theme names **/
+std::vector<std::string> getThemes();
+
/** Get full path to a share file **/
std::string getPath(fs::path const& filename);
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:45:52
|
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 31 13:00:11 2012 +0200
Fixed a bug in getThemePath.
---
game/fs.cc | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/game/fs.cc b/game/fs.cc
index 767a7ab..545206e 100644
--- a/game/fs.cc
+++ b/game/fs.cc
@@ -122,7 +122,7 @@ std::string getThemePath(std::string const& filename) {
if (theme.empty()) theme = defaultTheme;
// Try current theme and if that fails, try default theme and finally data dir
try { return getPath(fs::path("themes") / theme / filename); } catch (std::runtime_error&) {}
- if (theme == defaultTheme) try { return getPath(fs::path("themes") / defaultTheme / filename); } catch (std::runtime_error&) {}
+ if (theme != defaultTheme) try { return getPath(fs::path("themes") / defaultTheme / filename); } catch (std::runtime_error&) {}
return getPath(filename);
}
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:45:44
|
Author: Tapio Vierros <tap...@gm...>
Date: Mon Jan 23 20:15:15 2012 +0200
Started implementing more robust US txt multiplayer parser, with P3 support.
---
game/song.hh | 6 ++++-
game/songparser-txt.cc | 51 +++++++++++++++++++++++++++++++++++------------
game/songparser.hh | 3 +-
3 files changed, 45 insertions(+), 15 deletions(-)
diff --git a/game/song.hh b/game/song.hh
index 74c813a..726c0ca 100644
--- a/game/song.hh
+++ b/game/song.hh
@@ -60,9 +60,12 @@ class Song: boost::noncopyable {
Status status(double time);
int randomIdx; ///< sorting index used for random order
void insertVocalTrack(std::string vocalTrack, VocalTrack track) {
- vocalTracks.erase(vocalTrack);
+ eraseVocalTrack(vocalTrack);
vocalTracks.insert(std::make_pair<std::string, VocalTrack>(vocalTrack, track));
}
+ void eraseVocalTrack(std::string vocalTrack = TrackName::LEAD_VOCAL) {
+ vocalTracks.erase(vocalTrack);
+ }
// Get a selected track, or LEAD_VOCAL if not found or the first one if not found
VocalTrack& getVocalTrack(std::string vocalTrack = TrackName::LEAD_VOCAL) {
VocalTracks::iterator it = vocalTracks.find(vocalTrack);
@@ -82,6 +85,7 @@ class Song: boost::noncopyable {
}
return result;
}
+
InstrumentTracks instrumentTracks; ///< guitar etc. notes for this song
DanceTracks danceTracks; ///< dance tracks
bool hasDance() const { return !danceTracks.empty(); }
diff --git a/game/songparser-txt.cc b/game/songparser-txt.cc
index 665b9da..abaceaf 100644
--- a/game/songparser-txt.cc
+++ b/game/songparser-txt.cc
@@ -10,6 +10,10 @@
using namespace SongParserUtil;
+namespace {
+ const std::string DUET_P2 = "Duet singer"; // FIXME
+}
+
/// 'Magick' to check if this file looks like correct format
bool SongParser::txtCheck(std::vector<char> const& data) const {
return data[0] == '#' && data[1] >= 'A' && data[1] <= 'Z';
@@ -28,14 +32,28 @@ void SongParser::txtParseHeader() {
/// Parse notes
void SongParser::txtParse() {
std::string line;
- VocalTrack vocal(TrackName::LEAD_VOCAL);
+ m_curSinger = P1;
+ m_song.insertVocalTrack(TrackName::LEAD_VOCAL, VocalTrack(TrackName::LEAD_VOCAL));
+ m_song.insertVocalTrack(DUET_P2, VocalTrack(DUET_P2));
while (getline(line) && txtParseField(line)) {} // Parse the header again
resetNoteParsingState();
- while (txtParseNote(line, vocal) && getline(line)) {} // Parse notes
- // Workaround for the terminating : 1 0 0 line, written by some converters
- if (!vocal.notes.empty() && vocal.notes.back().type != Note::SLEEP
- && vocal.notes.back().begin == vocal.notes.back().end) vocal.notes.pop_back();
- m_song.insertVocalTrack(vocal.name, vocal);
+ while (txtParseNote(line) && getline(line)) {} // Parse notes
+
+ {
+ // Workaround for the terminating : 1 0 0 line, written by some converters
+ VocalTrack& vocal = m_song.getVocalTrack(TrackName::LEAD_VOCAL);
+ if (!vocal.notes.empty() && vocal.notes.back().type != Note::SLEEP
+ && vocal.notes.back().begin == vocal.notes.back().end) vocal.notes.pop_back();
+ }{
+ // Workaround for the terminating : 1 0 0 line, written by some converters
+ VocalTrack& vocal = m_song.getVocalTrack(DUET_P2);
+ if (!vocal.notes.empty() && vocal.notes.back().type != Note::SLEEP
+ && vocal.notes.back().begin == vocal.notes.back().end) vocal.notes.pop_back();
+ // Erase if empty
+ else if (vocal.notes.empty())
+ m_song.eraseVocalTrack(vocal.name);
+ }
+
}
bool SongParser::txtParseField(std::string const& line) {
@@ -66,7 +84,7 @@ bool SongParser::txtParseField(std::string const& line) {
return true;
}
-bool SongParser::txtParseNote(std::string line, VocalTrack &vocal) {
+bool SongParser::txtParseNote(std::string line) {
if (line.empty() || line == "\r") return true;
if (line[0] == '#') throw std::runtime_error("Key found in the middle of notes");
if (line[line.size() - 1] == '\r') line.erase(line.size() - 1);
@@ -81,13 +99,14 @@ bool SongParser::txtParseNote(std::string line, VocalTrack &vocal) {
return true;
}
if (line[0] == 'P') {
+ if (m_relative) // FIXME?
+ throw std::runtime_error("Relative note timing not supported with multiple singers");
if (line.size() < 2) throw std::runtime_error("Invalid player info line");
- if (line[1] == '1') return true;
- else if (line[1] == '2') {
- m_song.insertVocalTrack(vocal.name, vocal);
- vocal = VocalTrack("Singer 2"); // FIXME
- resetNoteParsingState();
- }
+ if (line[1] == '1') m_curSinger = P1;
+ else if (line[1] == '2') m_curSinger = P2;
+ else if (line[1] == '3') m_curSinger = BOTH;
+ else throw std::runtime_error("Invalid player info line");
+ resetNoteParsingState();
return true;
}
Note n;
@@ -121,9 +140,13 @@ bool SongParser::txtParseNote(std::string line, VocalTrack &vocal) {
default: throw std::runtime_error("Unknown note type");
}
n.begin = tsTime(ts);
+ VocalTrack& vocal = (m_curSinger & P1)
+ ? m_song.getVocalTrack(TrackName::LEAD_VOCAL)
+ : m_song.getVocalTrack(DUET_P2);
Notes& notes = vocal.notes;
if (m_relative && notes.empty()) m_relativeShift = ts;
m_prevts = ts;
+ // FIXME: These work-arounds don't work for P3 (both singers) case
if (n.begin < m_prevtime) {
// Oh no, overlapping notes (b0rked file)
// Can't do this because too many songs are b0rked: throw std::runtime_error("Note overlaps with previous note");
@@ -157,6 +180,8 @@ bool SongParser::txtParseNote(std::string line, VocalTrack &vocal) {
n.begin = n.end = prevtime; // Normalize sleep notes
}
notes.push_back(n);
+ if (m_curSinger == BOTH)
+ m_song.getVocalTrack(DUET_P2).notes.push_back(n);
return true;
}
diff --git a/game/songparser.hh b/game/songparser.hh
index 7962d8f..4cecd29 100644
--- a/game/songparser.hh
+++ b/game/songparser.hh
@@ -36,7 +36,7 @@ class SongParser {
void txtParseHeader();
void txtParse();
bool txtParseField(std::string const& line);
- bool txtParseNote(std::string line, VocalTrack &vocal);
+ bool txtParseNote(std::string line);
bool iniCheck(std::vector<char> const& data) const;
void iniParseHeader();
void iniParse();
@@ -55,6 +55,7 @@ class SongParser {
double m_prevtime;
unsigned int m_prevts;
unsigned int m_relativeShift;
+ enum CurrentSinger { P1 = 1, P2 = 2, BOTH = P1 | P2 } m_curSinger;
struct BPM {
BPM(double _begin, double _ts, double bpm): begin(_begin), step(0.25 * 60.0 / bpm), ts(_ts) {}
double begin; // Time in seconds
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:45:39
|
Author: Tapio Vierros <tap...@gm...>
Date: Mon Jan 23 19:36:31 2012 +0200
Optimize getVocalTrack.
---
game/song.hh | 22 +++++++++-------------
1 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/game/song.hh b/game/song.hh
index 16d3e16..74c813a 100644
--- a/game/song.hh
+++ b/game/song.hh
@@ -62,23 +62,19 @@ class Song: boost::noncopyable {
void insertVocalTrack(std::string vocalTrack, VocalTrack track) {
vocalTracks.erase(vocalTrack);
vocalTracks.insert(std::make_pair<std::string, VocalTrack>(vocalTrack, track));
- };
+ }
// Get a selected track, or LEAD_VOCAL if not found or the first one if not found
VocalTrack& getVocalTrack(std::string vocalTrack = TrackName::LEAD_VOCAL) {
- if(vocalTracks.find(vocalTrack) != vocalTracks.end()) {
- return vocalTracks.find(vocalTrack)->second;
+ VocalTracks::iterator it = vocalTracks.find(vocalTrack);
+ if (it != vocalTracks.end()) {
+ return it->second;
} else {
- if(vocalTracks.find(TrackName::LEAD_VOCAL) != vocalTracks.end()) {
- return vocalTracks.find(TrackName::LEAD_VOCAL)->second;
- } else {
- if(!vocalTracks.empty()) {
- return vocalTracks.begin()->second;
- } else {
- return dummyVocal;
- }
- }
+ it = vocalTracks.find(TrackName::LEAD_VOCAL);
+ if (it != vocalTracks.end()) return it->second;
+ else if (!vocalTracks.empty()) return vocalTracks.begin()->second;
+ else return dummyVocal;
}
- };
+ }
std::vector<std::string> getVocalTrackNames() {
std::vector<std::string> result;
BOOST_FOREACH(VocalTracks::value_type &it, vocalTracks) {
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:45:33
|
Author: Vincent Le Ligeour <yo...@us...>
Date: Mon Jan 23 01:40:29 2012 +0100
Removed harmonic track from header (it's FretsOfFire format only)
---
game/song.hh | 3 ---
game/songparser-mid.cc | 16 ++++++++++------
game/songparser-txt.cc | 2 +-
3 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/game/song.hh b/game/song.hh
index 82c4113..16d3e16 100644
--- a/game/song.hh
+++ b/game/song.hh
@@ -29,9 +29,6 @@ namespace TrackName {
const std::string KEYBOARD = "Keyboard";
const std::string DRUMS = "Drums";
const std::string LEAD_VOCAL = "Vocals";
- const std::string HARMONIC_1 = "Harmonic 1";
- const std::string HARMONIC_2 = "Harmonic 2";
- const std::string HARMONIC_3 = "Harmonic 3";
#if 0 // Here is some dummy gettext calls to populate the dictionary
_("Guitar") _("Coop guitar") _("Rhythm guitar") _("Bass") _("Drums") _("Vocals") _("Harmonic 1") _("Harmonic 2") _("Harmonic 3")
#endif
diff --git a/game/songparser-mid.cc b/game/songparser-mid.cc
index e944968..5068f49 100644
--- a/game/songparser-mid.cc
+++ b/game/songparser-mid.cc
@@ -11,6 +11,10 @@
using namespace SongParserUtil;
+const std::string HARMONIC_1 = "Harmonic 1";
+const std::string HARMONIC_2 = "Harmonic 2";
+const std::string HARMONIC_3 = "Harmonic 3";
+
namespace {
void testAndAdd(Song& s, std::string const& trackid, std::string const& filename) {
std::string f = s.path + filename;
@@ -18,9 +22,9 @@ namespace {
}
bool isVocalTrack(std::string name) {
if(name == TrackName::LEAD_VOCAL) return true;
- else if(name == TrackName::HARMONIC_1) return true;
- else if(name == TrackName::HARMONIC_2) return true;
- else if(name == TrackName::HARMONIC_3) return true;
+ else if(name == HARMONIC_1) return true;
+ else if(name == HARMONIC_2) return true;
+ else if(name == HARMONIC_3) return true;
return false;
}
/// Change the MIDI track name to Performous track name
@@ -39,9 +43,9 @@ namespace {
else if (name == "KEYS") return false; // TODO: RB3 5 lane keyboard track
else if (name == "GUITAR") name = TrackName::GUITAR;
else if (name == "VOCALS") name = TrackName::LEAD_VOCAL;
- else if (name == "HARM1") name = TrackName::HARMONIC_1;
- else if (name == "HARM2") name = TrackName::HARMONIC_2;
- else if (name == "HARM3") name = TrackName::HARMONIC_3;
+ else if (name == "HARM1") name = HARMONIC_1;
+ else if (name == "HARM2") name = HARMONIC_2;
+ else if (name == "HARM3") name = HARMONIC_3;
// expert stuffs
else if (name == "REAL_KEYS_X") return false; // TODO: RB3 pro keyboard expert track
else if (name == "REAL_KEYS_H") return false; // TODO: RB3 pro keyboard hard track
diff --git a/game/songparser-txt.cc b/game/songparser-txt.cc
index 6744eaf..665b9da 100644
--- a/game/songparser-txt.cc
+++ b/game/songparser-txt.cc
@@ -85,7 +85,7 @@ bool SongParser::txtParseNote(std::string line, VocalTrack &vocal) {
if (line[1] == '1') return true;
else if (line[1] == '2') {
m_song.insertVocalTrack(vocal.name, vocal);
- vocal = VocalTrack(TrackName::HARMONIC_1);
+ vocal = VocalTrack("Singer 2"); // FIXME
resetNoteParsingState();
}
return true;
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:45:25
|
Author: Vincent Le Ligeour <yo...@us...> Date: Mon Jan 23 01:33:18 2012 +0100 Added SingStar XML format parsing --- game/songparser-xml.cc | 321 ++++++++++++++++++++++++++++++++++++++++++++++++ game/songparser.cc | 5 +- game/songparser.hh | 3 + game/songs.cc | 2 +- 4 files changed, 329 insertions(+), 2 deletions(-) |
|
From: rainbyte <rai...@us...> - 2012-07-17 10:45:18
|
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 17 23:33:42 2012 +0200
Support for UltraStar TXT multiplayer duet note parsing.
Needs more testing.
---
game/songparser-txt.cc | 15 ++++++++++++---
game/songparser.cc | 9 +++++++++
game/songparser.hh | 1 +
3 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/game/songparser-txt.cc b/game/songparser-txt.cc
index 06221b3..6744eaf 100644
--- a/game/songparser-txt.cc
+++ b/game/songparser-txt.cc
@@ -30,12 +30,12 @@ void SongParser::txtParse() {
std::string line;
VocalTrack vocal(TrackName::LEAD_VOCAL);
while (getline(line) && txtParseField(line)) {} // Parse the header again
- if (m_bpm != 0.0) addBPM(0, m_bpm);
+ resetNoteParsingState();
while (txtParseNote(line, vocal) && getline(line)) {} // Parse notes
// Workaround for the terminating : 1 0 0 line, written by some converters
if (!vocal.notes.empty() && vocal.notes.back().type != Note::SLEEP
&& vocal.notes.back().begin == vocal.notes.back().end) vocal.notes.pop_back();
- m_song.insertVocalTrack(TrackName::LEAD_VOCAL, vocal);
+ m_song.insertVocalTrack(vocal.name, vocal);
}
bool SongParser::txtParseField(std::string const& line) {
@@ -80,7 +80,16 @@ bool SongParser::txtParseNote(std::string line, VocalTrack &vocal) {
addBPM(ts, bpm);
return true;
}
- if (line[0] == 'P') return true; //We ignore player information for now (multiplayer hack)
+ if (line[0] == 'P') {
+ if (line.size() < 2) throw std::runtime_error("Invalid player info line");
+ if (line[1] == '1') return true;
+ else if (line[1] == '2') {
+ m_song.insertVocalTrack(vocal.name, vocal);
+ vocal = VocalTrack(TrackName::HARMONIC_1);
+ resetNoteParsingState();
+ }
+ return true;
+ }
Note n;
n.type = Note::Type(iss.get());
unsigned int ts = m_prevts;
diff --git a/game/songparser.cc b/game/songparser.cc
index ac9f3f6..f3a2862 100644
--- a/game/songparser.cc
+++ b/game/songparser.cc
@@ -117,6 +117,15 @@ SongParser::SongParser(Song& s):
s.loadStatus = Song::HEADER;
}
+void SongParser::resetNoteParsingState() {
+ m_prevtime = 0;
+ m_prevts = 0;
+ m_relativeShift = 0;
+ m_tsPerBeat = 0;
+ m_tsEnd = 0;
+ m_bpms.clear();
+ if (m_bpm != 0.0) addBPM(0, m_bpm);
+}
void SongParser::finalize() {
std::vector<std::string> tracks = m_song.getVocalTrackNames();
diff --git a/game/songparser.hh b/game/songparser.hh
index 7355a33..0347559 100644
--- a/game/songparser.hh
+++ b/game/songparser.hh
@@ -48,6 +48,7 @@ class SongParser {
void smParse();
bool smParseField(std::string line);
Notes smParseNotes(std::string line);
+ void resetNoteParsingState();
double m_prevtime;
unsigned int m_prevts;
unsigned int m_relativeShift;
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:45:10
|
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 17 21:42:29 2012 +0200
Full screen singer layout if only one mic available.
---
game/screen_sing.cc | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index eeb8240..dfb7a9e 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -60,10 +60,11 @@ void ScreenSing::enter() {
selectedTracks.push_back(&m_song->getVocalTrack(m_selectedTrack));
m_layout_singer.clear();
m_layout_singer.push_back(new LayoutSinger(*selectedTracks.back(), m_database, theme));
- // Find out if we have multiple vocal tracks and create layouts for them, up to a total of 2
+ // Do we have a second vocal track and a singer for it?
std::vector<std::string> tracks = m_song->getVocalTrackNames();
- for (size_t i = 1; i < std::min((int)tracks.size(), 2); ++i) {
- selectedTracks.push_back(&m_song->getVocalTrack(tracks[i]));
+ if (tracks.size() > 1 && analyzers.size() > 1) {
+ // TODO: Maybe should check that tracks[1] is not LEAD_VOCALS
+ selectedTracks.push_back(&m_song->getVocalTrack(tracks[1]));
m_layout_singer.push_back(new LayoutSinger(*selectedTracks.back(), m_database, theme));
}
// Load instrument and dance tracks
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:45:07
|
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 17 21:28:10 2012 +0200
Draw player scores etc only in their corresponding singer layout.
---
game/layout_singer.cc | 28 +++++++++++++++-------------
1 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/game/layout_singer.cc b/game/layout_singer.cc
index 4f0645c..9d52d7c 100644
--- a/game/layout_singer.cc
+++ b/game/layout_singer.cc
@@ -29,8 +29,9 @@ void LayoutSinger::reset() {
}
void LayoutSinger::drawScore(PositionMode position) {
- unsigned int i = 0;
+ unsigned int i = 0, j = 0;
for (std::list<Player>::const_iterator p = m_database.cur.begin(); p != m_database.cur.end(); ++p, ++i) {
+ if (p->m_vocal.name != m_vocal.name) continue;
float act = p->activity();
if (act == 0.0f) continue;
float r = p->m_color.r;
@@ -39,21 +40,21 @@ void LayoutSinger::drawScore(PositionMode position) {
m_score_text[i%4]->render((boost::format("%04d") % p->getScore()).str());
switch(position) {
case LayoutSinger::FULL:
- m_player_icon->dimensions.left(-0.5 + 0.01 + 0.25 * i).fixedWidth(0.075).screenTop(0.055);
- m_score_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * i).fixedHeight(0.075).screenTop(0.055);
+ m_player_icon->dimensions.left(-0.5 + 0.01 + 0.25 * j).fixedWidth(0.075).screenTop(0.055);
+ m_score_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * j).fixedHeight(0.075).screenTop(0.055);
break;
case LayoutSinger::TOP:
- m_player_icon->dimensions.right(0.35).fixedHeight(0.050).screenTop(0.025 + 0.050 * i);
- m_score_text[i%4]->dimensions().right(0.45).fixedHeight(0.050).screenTop(0.025 + 0.050 * i);
+ m_player_icon->dimensions.right(0.35).fixedHeight(0.050).screenTop(0.025 + 0.050 * j);
+ m_score_text[i%4]->dimensions().right(0.45).fixedHeight(0.050).screenTop(0.025 + 0.050 * j);
break;
case LayoutSinger::BOTTOM:
- m_player_icon->dimensions.right(0.35).fixedHeight(0.050).center(0.025 + 0.050 * i);
- m_score_text[i%4]->dimensions().right(0.45).fixedHeight(0.050).center(0.025 + 0.050 * i);
+ m_player_icon->dimensions.right(0.35).fixedHeight(0.050).center(0.025 + 0.050 * j);
+ m_score_text[i%4]->dimensions().right(0.45).fixedHeight(0.050).center(0.025 + 0.050 * j);
break;
case LayoutSinger::LEFT:
case LayoutSinger::RIGHT:
- m_player_icon->dimensions.left(-0.5 + 0.01 + 0.25 * i).fixedWidth(0.075).screenTop(0.055);
- m_score_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * i).fixedHeight(0.075).screenTop(0.055);
+ m_player_icon->dimensions.left(-0.5 + 0.01 + 0.25 * j).fixedWidth(0.075).screenTop(0.055);
+ m_score_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * j).fixedHeight(0.075).screenTop(0.055);
break;
}
{
@@ -74,17 +75,17 @@ void LayoutSinger::drawScore(PositionMode position) {
m_line_rank_text[i%4]->render(prevLineRank);
switch(position) {
case LayoutSinger::FULL:
- m_line_rank_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * i).fixedHeight(0.055*fzoom).screenTop(0.11);
+ m_line_rank_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * j).fixedHeight(0.055*fzoom).screenTop(0.11);
break;
case LayoutSinger::TOP:
- m_line_rank_text[i%4]->dimensions().right(0.30).fixedHeight(0.05*fzoom).screenTop(0.025 + 0.050 * i);
+ m_line_rank_text[i%4]->dimensions().right(0.30).fixedHeight(0.05*fzoom).screenTop(0.025 + 0.050 * j);
break;
case LayoutSinger::BOTTOM:
- m_line_rank_text[i%4]->dimensions().right(0.30).fixedHeight(0.05*fzoom).center(0.025 + 0.050 * i);
+ m_line_rank_text[i%4]->dimensions().right(0.30).fixedHeight(0.05*fzoom).center(0.025 + 0.050 * j);
break;
case LayoutSinger::LEFT:
case LayoutSinger::RIGHT:
- m_line_rank_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * i).fixedHeight(0.055*fzoom).screenTop(0.11);
+ m_line_rank_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * j).fixedHeight(0.055*fzoom).screenTop(0.11);
break;
}
{
@@ -92,6 +93,7 @@ void LayoutSinger::drawScore(PositionMode position) {
m_line_rank_text[i%4]->draw();
}
}
+ ++j;
}
}
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:44:58
|
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 17 21:27:35 2012 +0200
Draw pitch waves only in their correct notegraph.
---
game/notegraph.cc | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/game/notegraph.cc b/game/notegraph.cc
index c8ce4c6..e70fe5c 100644
--- a/game/notegraph.cc
+++ b/game/notegraph.cc
@@ -197,6 +197,8 @@ void NoteGraph::drawWaves(Database const& database) {
UseTexture tblock(m_wave);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);
for (std::list<Player>::const_iterator p = database.cur.begin(); p != database.cur.end(); ++p) {
+ if (p->m_vocal.name != m_vocal.name)
+ continue;
float const texOffset = 2.0 * m_time; // Offset for animating the wave texture
Player::pitch_t const& pitch = p->m_pitch;
size_t const beginIdx = std::max(0.0, m_time - 0.5 / pixUnit) / Engine::TIMESTEP; // At which pitch idx to start displaying the wave
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:44:52
|
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 17 21:12:57 2012 +0200
Engine work for duet: now different tracks are analyzed.
Contains some FIXMEs though.
---
game/engine.hh | 26 +++++++++++++++++---------
game/screen_sing.cc | 14 +++++++++-----
2 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/game/engine.hh b/game/engine.hh
index 7fed62d..7ebeeb6 100644
--- a/game/engine.hh
+++ b/game/engine.hh
@@ -12,13 +12,13 @@
/// performous engine
class Engine {
Audio& m_audio;
- VocalTrack& m_vocal;
size_t m_time;
volatile bool m_quit;
Database& m_database;
boost::scoped_ptr<boost::thread> m_thread;
public:
+ typedef std::vector<VocalTrack*> VocalTrackPtrs;
/// timestepping constant
static const double TIMESTEP;
/** Construct a new Engine with the players that go with it.
@@ -28,17 +28,24 @@ class Engine {
* @param anEnd Analyzers to use (ending iterator)
* @param vocal Song to play
**/
- template <typename FwdIt> Engine(Audio& audio, VocalTrack& vocal, FwdIt anBegin, FwdIt anEnd, Database& database):
- m_audio(audio), m_vocal(vocal), m_time(), m_quit(), m_database(database)
+ template <typename FwdIt> Engine(Audio& audio, VocalTrackPtrs vocals, FwdIt anBegin, FwdIt anEnd, Database& database):
+ m_audio(audio), m_time(), m_quit(), m_database(database)
{
- // clear old player information
+ if (vocals.empty())
+ throw std::runtime_error("Engine needs at least one vocal track");
+ // Remove unsensibly long tracks
+ for (VocalTrackPtrs::iterator it = vocals.begin(); it != vocals.end(); )
+ if (!(*it) || (*it)->endTime > 10000.0) it = vocals.erase(it);
+ else ++it;
+ // Clear old player information
m_database.cur.clear();
m_database.scores.clear();
- // Only add players if the vocal track has sensible length (not NaN or extremely long)
- if (vocal.endTime < 10000.0) {
+ size_t i = 0;
+ while (anBegin != anEnd && !vocals.empty()) {
// Calculate the space required for pitch frames
- size_t frames = vocal.endTime / Engine::TIMESTEP;
- while (anBegin != anEnd) m_database.cur.push_back(Player(vocal, *anBegin++, frames));
+ size_t frames = vocals[i]->endTime / Engine::TIMESTEP;
+ m_database.cur.push_back(Player(*vocals[i], *anBegin++, frames));
+ i = (i+1) % vocals.size();
}
m_thread.reset(new boost::thread(boost::ref(*this)));
}
@@ -53,7 +60,8 @@ class Engine {
double timeLeft = m_time * TIMESTEP - t;
if (timeLeft != timeLeft || timeLeft > 1.0) timeLeft = 1.0; // FIXME: Workaround for NaN values and other weirdness (should fix the weirdness instead)
if (timeLeft > 0.0) { boost::thread::sleep(now() + std::min(TIMESTEP, timeLeft)); continue; }
- for (Notes::const_iterator it = m_vocal.notes.begin(); it != m_vocal.notes.end(); ++it) it->power = 0.0f;
+ // FIXME: Implement
+ //for (Notes::const_iterator it = m_vocal.notes.begin(); it != m_vocal.notes.end(); ++it) it->power = 0.0f;
std::for_each(m_database.cur.begin(), m_database.cur.end(), boost::bind(&Player::update, _1));
++m_time;
}
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index 31ab59c..eeb8240 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -56,12 +56,15 @@ void ScreenSing::enter() {
boost::ptr_vector<Analyzer>& analyzers = m_audio.analyzers();
reloadGL();
// Add a singer layout
+ Engine::VocalTrackPtrs selectedTracks;
+ selectedTracks.push_back(&m_song->getVocalTrack(m_selectedTrack));
m_layout_singer.clear();
- m_layout_singer.push_back(new LayoutSinger(m_song->getVocalTrack(m_selectedTrack), m_database, theme));
+ m_layout_singer.push_back(new LayoutSinger(*selectedTracks.back(), m_database, theme));
// Find out if we have multiple vocal tracks and create layouts for them, up to a total of 2
std::vector<std::string> tracks = m_song->getVocalTrackNames();
for (size_t i = 1; i < std::min((int)tracks.size(), 2); ++i) {
- m_layout_singer.push_back(new LayoutSinger(m_song->getVocalTrack(tracks[i]), m_database, theme));
+ selectedTracks.push_back(&m_song->getVocalTrack(tracks[i]));
+ m_layout_singer.push_back(new LayoutSinger(*selectedTracks.back(), m_database, theme));
}
// Load instrument and dance tracks
sm->loading(_("Loading instruments..."), 0.8);
@@ -100,12 +103,13 @@ void ScreenSing::enter() {
opts.push_back(*it);
}
m_vocalTrackOpts = ConfigItem(opts); // Create a ConfigItem from the option list
- if (opts.size() > 1) { // Vocal track changer only if there is options
+ // FIXME: Add a duet option without breaking track selector
+ /*if (opts.size() > 1) { // Vocal track changer only if there is options
m_vocalTrackOpts.select(cur); // Set the selection to current track
m_menu.add(MenuOption("", _("Change vocal track\n(restart required)"), &m_vocalTrackOpts));
m_selectedTrackLocalized = _(m_selectedTrack.c_str());
m_menu.back().setDynamicName(m_selectedTrackLocalized); // Set the title to be dynamic
- }
+ }*/
}
m_menu.add(MenuOption(_("Quit"), _("Exit to song browser"), "Songs"));
m_menu.close();
@@ -113,7 +117,7 @@ void ScreenSing::enter() {
double setup_delay = (m_instruments.empty() && m_dancers.empty() ? -1.0 : -5.0);
sm->loading(_("Finalizing..."), 0.95);
m_audio.playMusic(m_song->music, false, 0.0, setup_delay);
- m_engine.reset(new Engine(m_audio, m_song->getVocalTrack(m_selectedTrack), analyzers.begin(), analyzers.end(), m_database));
+ m_engine.reset(new Engine(m_audio, selectedTracks, analyzers.begin(), analyzers.end(), m_database));
// Notify about broken tracks
if (m_song->b0rkedTracks) ScreenManager::getSingletonPtr()->dialog(_("Song contains broken tracks!"));
sm->showLogo(false);
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:44:49
|
Author: Tapio Vierros <tap...@gm...>
Date: Sun Dec 18 19:37:53 2011 +0200
Disable joining with keyboard starpower since CTRL is used for e.g. seeking.
---
game/guitargraph.cc | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index aeb9d30..20883b3 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -316,9 +316,10 @@ void GuitarGraph::engine() {
bool difficulty_changed = false;
// Handle all events
for (input::Event ev; m_input.tryPoll(ev);) {
- // This hack disallows joining with Enter-key for skipping instrumental
- // breaks to be usable with FoF songs.
- if (dead() && m_input.isKeyboard() && ev.type == input::Event::PICK) continue;
+ // This hack disallows joining with Enter and CTRL-key
+ // since they cause issues due to also being used in other places
+ if (dead() && m_input.isKeyboard()
+ && (ev.type == input::Event::PICK || ev.button == input::GODMODE_BUTTON)) continue;
m_dead = 0; // Keep alive
// Handle joining
if (m_jointime != m_jointime) {
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:44:42
|
Author: Tapio Vierros <tap...@gm...>
Date: Sun Dec 18 19:30:43 2011 +0200
Display bottom lyrics further down in duet mode.
---
game/layout_singer.cc | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/game/layout_singer.cc b/game/layout_singer.cc
index 14e1100..4f0645c 100644
--- a/game/layout_singer.cc
+++ b/game/layout_singer.cc
@@ -129,7 +129,7 @@ void LayoutSinger::draw(double time, PositionMode position) {
linespacing = 0.04;
break;
case LayoutSinger::BOTTOM:
- pos.screenBottom(-0.1);
+ pos.screenBottom(-0.05);
linespacing = 0.04;
break;
case LayoutSinger::LEFT:
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:44:34
|
Author: Tapio Vierros <tap...@gm...>
Date: Sun Dec 18 19:28:44 2011 +0200
Create and display two LayoutSingers if more than one VocalTrack is found.
---
game/screen_sing.cc | 38 +++++++++++++++++++++++++-------------
game/screen_sing.hh | 2 +-
2 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index c6e249d..31ab59c 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -55,7 +55,14 @@ void ScreenSing::enter() {
}
boost::ptr_vector<Analyzer>& analyzers = m_audio.analyzers();
reloadGL();
- m_layout_singer.reset(new LayoutSinger(m_song->getVocalTrack(m_selectedTrack), m_database, theme));
+ // Add a singer layout
+ m_layout_singer.clear();
+ m_layout_singer.push_back(new LayoutSinger(m_song->getVocalTrack(m_selectedTrack), m_database, theme));
+ // Find out if we have multiple vocal tracks and create layouts for them, up to a total of 2
+ std::vector<std::string> tracks = m_song->getVocalTrackNames();
+ for (size_t i = 1; i < std::min((int)tracks.size(), 2); ++i) {
+ m_layout_singer.push_back(new LayoutSinger(m_song->getVocalTrack(tracks[i]), m_database, theme));
+ }
// Load instrument and dance tracks
sm->loading(_("Loading instruments..."), 0.8);
{
@@ -153,7 +160,7 @@ void ScreenSing::exit() {
m_menu.clear();
m_instruments.clear();
m_dancers.clear();
- m_layout_singer.reset();
+ m_layout_singer.clear();
m_help.reset();
m_pause_icon.reset();
m_cam.reset();
@@ -328,7 +335,8 @@ void ScreenSing::manageEvent(SDL_Event event) {
else if (status == Song::INSTRUMENTAL_BREAK) {
if (time < 0) m_audio.seek(0.0);
else {
- double diff = m_layout_singer->lyrics_begin() - 3.0 - time;
+ // FIXME: Should check for all layout singers
+ double diff = m_layout_singer[0].lyrics_begin() - 3.0 - time;
if (diff > 0.0) m_audio.seek(diff);
}
}
@@ -377,7 +385,9 @@ void ScreenSing::manageEvent(SDL_Event event) {
}
// Some things must be reset after seeking backwards
- if (seekback) m_layout_singer->reset();
+ if (seekback)
+ for (int i = 0; i < m_layout_singer.size(); ++i)
+ m_layout_singer[i].reset();
// Reload current song
if (key == SDLK_r) {
exit(); m_song->reload(); enter();
@@ -451,21 +461,23 @@ void ScreenSing::draw() {
theme->bg_top.draw();
}
- m_layout_singer->hideLyrics(m_audio.isPaused());
+ for (int i = 0; i < m_layout_singer.size(); ++i)
+ m_layout_singer[i].hideLyrics(m_audio.isPaused());
// Dancing
- if( !m_dancers.empty() ) {
+ if (!m_dancers.empty()) {
danceLayout(time);
//m_layout_singer->draw(time, LayoutSinger::LEFT);
m_only_singers_alive = false;
- // Singing only
- } else if( m_instruments.empty() ) {
- m_layout_singer->draw(time, LayoutSinger::FULL);
- m_only_singers_alive = true;
- // Band
+ // Singing & band
} else {
- m_only_singers_alive = !instrumentLayout(time);
- m_layout_singer->draw(time, m_only_singers_alive ? LayoutSinger::FULL : LayoutSinger::TOP);
+ if (m_instruments.empty()) m_only_singers_alive = true;
+ else m_only_singers_alive = !instrumentLayout(time);
+
+ bool fullSinger = m_only_singers_alive && m_layout_singer.size() <= 1;
+ m_layout_singer[0].draw(time, fullSinger ? LayoutSinger::FULL : LayoutSinger::TOP);
+ if (m_layout_singer.size() > 1)
+ m_layout_singer[1].draw(time, LayoutSinger::BOTTOM);
}
Song::Status status = m_song->status(time);
diff --git a/game/screen_sing.hh b/game/screen_sing.hh
index b3dd744..a5a5a74 100644
--- a/game/screen_sing.hh
+++ b/game/screen_sing.hh
@@ -85,7 +85,7 @@ class ScreenSing: public Screen {
boost::scoped_ptr<Surface> m_pause_icon;
boost::scoped_ptr<Surface> m_help;
boost::scoped_ptr<Engine> m_engine;
- boost::scoped_ptr<LayoutSinger> m_layout_singer;
+ boost::ptr_vector<LayoutSinger> m_layout_singer;
boost::scoped_ptr<ThemeInstrumentMenu> m_menuTheme;
Menu m_menu;
Instruments m_instruments;
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:44:31
|
Author: Tapio Vierros <tap...@gm...>
Date: Sun Dec 18 18:36:02 2011 +0200
Change of plans: LayoutSinger will only handle one VocalTrack.
---
game/layout_singer.cc | 32 ++++++++++++++++++--------------
game/layout_singer.hh | 2 +-
game/screen_players.cc | 2 +-
game/screen_sing.cc | 2 +-
4 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/game/layout_singer.cc b/game/layout_singer.cc
index d637634..14e1100 100644
--- a/game/layout_singer.cc
+++ b/game/layout_singer.cc
@@ -38,15 +38,18 @@ void LayoutSinger::drawScore(PositionMode position) {
float b = p->m_color.b;
m_score_text[i%4]->render((boost::format("%04d") % p->getScore()).str());
switch(position) {
- case LayoutSinger::DUET:
case LayoutSinger::FULL:
m_player_icon->dimensions.left(-0.5 + 0.01 + 0.25 * i).fixedWidth(0.075).screenTop(0.055);
m_score_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * i).fixedHeight(0.075).screenTop(0.055);
break;
- case LayoutSinger::BAND:
+ case LayoutSinger::TOP:
m_player_icon->dimensions.right(0.35).fixedHeight(0.050).screenTop(0.025 + 0.050 * i);
m_score_text[i%4]->dimensions().right(0.45).fixedHeight(0.050).screenTop(0.025 + 0.050 * i);
break;
+ case LayoutSinger::BOTTOM:
+ m_player_icon->dimensions.right(0.35).fixedHeight(0.050).center(0.025 + 0.050 * i);
+ m_score_text[i%4]->dimensions().right(0.45).fixedHeight(0.050).center(0.025 + 0.050 * i);
+ break;
case LayoutSinger::LEFT:
case LayoutSinger::RIGHT:
m_player_icon->dimensions.left(-0.5 + 0.01 + 0.25 * i).fixedWidth(0.075).screenTop(0.055);
@@ -70,13 +73,15 @@ void LayoutSinger::drawScore(PositionMode position) {
else if (p->m_prevLineScore > 0.4) prevLineRank = "OK";
m_line_rank_text[i%4]->render(prevLineRank);
switch(position) {
- case LayoutSinger::DUET:
case LayoutSinger::FULL:
m_line_rank_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * i).fixedHeight(0.055*fzoom).screenTop(0.11);
break;
- case LayoutSinger::BAND:
+ case LayoutSinger::TOP:
m_line_rank_text[i%4]->dimensions().right(0.30).fixedHeight(0.05*fzoom).screenTop(0.025 + 0.050 * i);
break;
+ case LayoutSinger::BOTTOM:
+ m_line_rank_text[i%4]->dimensions().right(0.30).fixedHeight(0.05*fzoom).center(0.025 + 0.050 * i);
+ break;
case LayoutSinger::LEFT:
case LayoutSinger::RIGHT:
m_line_rank_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * i).fixedHeight(0.055*fzoom).screenTop(0.11);
@@ -94,17 +99,15 @@ void LayoutSinger::draw(double time, PositionMode position) {
// Draw notes and pitch waves (only when not in karaoke mode)
if (!config["game/karaoke_mode"].b()) {
switch(position) {
- case LayoutSinger::DUET:
- // TODO: Individual NoteGraphs
- m_noteGraph.draw(time, m_database, NoteGraph::TOP);
- m_noteGraph.draw(time, m_database, NoteGraph::BOTTOM);
- break;
case LayoutSinger::FULL:
m_noteGraph.draw(time, m_database, NoteGraph::FULLSCREEN);
break;
- case LayoutSinger::BAND:
+ case LayoutSinger::TOP:
m_noteGraph.draw(time, m_database, NoteGraph::TOP);
break;
+ case LayoutSinger::BOTTOM:
+ m_noteGraph.draw(time, m_database, NoteGraph::BOTTOM);
+ break;
case LayoutSinger::LEFT:
case LayoutSinger::RIGHT:
m_noteGraph.draw(time, m_database, NoteGraph::LEFT);
@@ -121,13 +124,14 @@ void LayoutSinger::draw(double time, PositionMode position) {
pos.screenBottom(-0.1);
linespacing = 0.06;
break;
- case LayoutSinger::DUET:
- // TODO: Implement
- //break;
- case LayoutSinger::BAND:
+ case LayoutSinger::TOP:
pos.center(-0.05);
linespacing = 0.04;
break;
+ case LayoutSinger::BOTTOM:
+ pos.screenBottom(-0.1);
+ linespacing = 0.04;
+ break;
case LayoutSinger::LEFT:
case LayoutSinger::RIGHT:
pos.screenBottom(-0.1);
diff --git a/game/layout_singer.hh b/game/layout_singer.hh
index e9becc9..235889a 100644
--- a/game/layout_singer.hh
+++ b/game/layout_singer.hh
@@ -49,7 +49,7 @@ class LyricRow {
class LayoutSinger {
public:
- enum PositionMode {FULL, DUET, BAND, LEFT, RIGHT};
+ enum PositionMode {FULL, TOP, BOTTOM, LEFT, RIGHT};
/// ThemeSing is optional if you want to use drawScore only
LayoutSinger(VocalTrack& vocal, Database& database, boost::shared_ptr<ThemeSing> theme = boost::shared_ptr<ThemeSing>());
~LayoutSinger();
diff --git a/game/screen_players.cc b/game/screen_players.cc
index dd1d60e..9f49b6d 100644
--- a/game/screen_players.cc
+++ b/game/screen_players.cc
@@ -175,6 +175,6 @@ void ScreenPlayers::draw() {
if (!video.empty() && config["graphic/video"].b()) m_video.reset(new Video(video, videoGap));
m_playing = music;
}
- m_layout_singer->drawScore(LayoutSinger::BAND);
+ m_layout_singer->drawScore(LayoutSinger::TOP);
}
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index bab75ba..c6e249d 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -465,7 +465,7 @@ void ScreenSing::draw() {
// Band
} else {
m_only_singers_alive = !instrumentLayout(time);
- m_layout_singer->draw(time, m_only_singers_alive ? LayoutSinger::FULL : LayoutSinger::BAND);
+ m_layout_singer->draw(time, m_only_singers_alive ? LayoutSinger::FULL : LayoutSinger::TOP);
}
Song::Status status = m_song->status(time);
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:44:24
|
Author: Tapio Vierros <tap...@gm...>
Date: Sun Dec 18 18:22:40 2011 +0200
Added mostly dummy LayoutSinger::PositionMode::DUET.
---
game/layout_singer.cc | 26 ++++++++++++++++++--------
game/layout_singer.hh | 2 +-
2 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/game/layout_singer.cc b/game/layout_singer.cc
index ae4a6e9..d637634 100644
--- a/game/layout_singer.cc
+++ b/game/layout_singer.cc
@@ -38,11 +38,12 @@ void LayoutSinger::drawScore(PositionMode position) {
float b = p->m_color.b;
m_score_text[i%4]->render((boost::format("%04d") % p->getScore()).str());
switch(position) {
- case LayoutSinger::FULL: // Fullscreen
+ case LayoutSinger::DUET:
+ case LayoutSinger::FULL:
m_player_icon->dimensions.left(-0.5 + 0.01 + 0.25 * i).fixedWidth(0.075).screenTop(0.055);
m_score_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * i).fixedHeight(0.075).screenTop(0.055);
break;
- case LayoutSinger::BAND: // Band mode
+ case LayoutSinger::BAND:
m_player_icon->dimensions.right(0.35).fixedHeight(0.050).screenTop(0.025 + 0.050 * i);
m_score_text[i%4]->dimensions().right(0.45).fixedHeight(0.050).screenTop(0.025 + 0.050 * i);
break;
@@ -69,10 +70,11 @@ void LayoutSinger::drawScore(PositionMode position) {
else if (p->m_prevLineScore > 0.4) prevLineRank = "OK";
m_line_rank_text[i%4]->render(prevLineRank);
switch(position) {
- case LayoutSinger::FULL: // Fullscreen
+ case LayoutSinger::DUET:
+ case LayoutSinger::FULL:
m_line_rank_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * i).fixedHeight(0.055*fzoom).screenTop(0.11);
break;
- case LayoutSinger::BAND: // Band mode
+ case LayoutSinger::BAND:
m_line_rank_text[i%4]->dimensions().right(0.30).fixedHeight(0.05*fzoom).screenTop(0.025 + 0.050 * i);
break;
case LayoutSinger::LEFT:
@@ -92,10 +94,15 @@ void LayoutSinger::draw(double time, PositionMode position) {
// Draw notes and pitch waves (only when not in karaoke mode)
if (!config["game/karaoke_mode"].b()) {
switch(position) {
- case LayoutSinger::FULL: // Fullscreen
+ case LayoutSinger::DUET:
+ // TODO: Individual NoteGraphs
+ m_noteGraph.draw(time, m_database, NoteGraph::TOP);
+ m_noteGraph.draw(time, m_database, NoteGraph::BOTTOM);
+ break;
+ case LayoutSinger::FULL:
m_noteGraph.draw(time, m_database, NoteGraph::FULLSCREEN);
break;
- case LayoutSinger::BAND: // Band mode
+ case LayoutSinger::BAND:
m_noteGraph.draw(time, m_database, NoteGraph::TOP);
break;
case LayoutSinger::LEFT:
@@ -110,11 +117,14 @@ void LayoutSinger::draw(double time, PositionMode position) {
double linespacing = 0.0;
Dimensions pos;
switch(position) {
- case LayoutSinger::FULL: // Fullscreen
+ case LayoutSinger::FULL:
pos.screenBottom(-0.1);
linespacing = 0.06;
break;
- case LayoutSinger::BAND: // Band mode
+ case LayoutSinger::DUET:
+ // TODO: Implement
+ //break;
+ case LayoutSinger::BAND:
pos.center(-0.05);
linespacing = 0.04;
break;
diff --git a/game/layout_singer.hh b/game/layout_singer.hh
index a948f5b..e9becc9 100644
--- a/game/layout_singer.hh
+++ b/game/layout_singer.hh
@@ -49,7 +49,7 @@ class LyricRow {
class LayoutSinger {
public:
- enum PositionMode {FULL, BAND, LEFT, RIGHT};
+ enum PositionMode {FULL, DUET, BAND, LEFT, RIGHT};
/// ThemeSing is optional if you want to use drawScore only
LayoutSinger(VocalTrack& vocal, Database& database, boost::shared_ptr<ThemeSing> theme = boost::shared_ptr<ThemeSing>());
~LayoutSinger();
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:44:18
|
Author: Tapio Vierros <tap...@gm...>
Date: Sun Dec 18 18:02:39 2011 +0200
Made LayoutSinger enum values more informative.
---
game/layout_singer.cc | 24 ++++++++++++------------
game/layout_singer.hh | 8 ++++----
game/screen_players.cc | 2 +-
game/screen_sing.cc | 4 ++--
4 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/game/layout_singer.cc b/game/layout_singer.cc
index 09eac21..ae4a6e9 100644
--- a/game/layout_singer.cc
+++ b/game/layout_singer.cc
@@ -21,14 +21,14 @@ LayoutSinger::LayoutSinger(VocalTrack& vocal, Database& database, boost::shared_
m_player_icon.reset(new Surface(getThemePath("sing_pbox.svg")));
}
-LayoutSinger::~LayoutSinger() {};
+LayoutSinger::~LayoutSinger() {}
void LayoutSinger::reset() {
m_lyricit = m_vocal.notes.begin();
m_lyrics.clear();
}
-void LayoutSinger::drawScore(Position position) {
+void LayoutSinger::drawScore(PositionMode position) {
unsigned int i = 0;
for (std::list<Player>::const_iterator p = m_database.cur.begin(); p != m_database.cur.end(); ++p, ++i) {
float act = p->activity();
@@ -38,11 +38,11 @@ void LayoutSinger::drawScore(Position position) {
float b = p->m_color.b;
m_score_text[i%4]->render((boost::format("%04d") % p->getScore()).str());
switch(position) {
- case LayoutSinger::BOTTOM: // Fullscreen
+ case LayoutSinger::FULL: // Fullscreen
m_player_icon->dimensions.left(-0.5 + 0.01 + 0.25 * i).fixedWidth(0.075).screenTop(0.055);
m_score_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * i).fixedHeight(0.075).screenTop(0.055);
break;
- case LayoutSinger::MIDDLE: // Band mode
+ case LayoutSinger::BAND: // Band mode
m_player_icon->dimensions.right(0.35).fixedHeight(0.050).screenTop(0.025 + 0.050 * i);
m_score_text[i%4]->dimensions().right(0.45).fixedHeight(0.050).screenTop(0.025 + 0.050 * i);
break;
@@ -69,10 +69,10 @@ void LayoutSinger::drawScore(Position position) {
else if (p->m_prevLineScore > 0.4) prevLineRank = "OK";
m_line_rank_text[i%4]->render(prevLineRank);
switch(position) {
- case LayoutSinger::BOTTOM: // Fullscreen
+ case LayoutSinger::FULL: // Fullscreen
m_line_rank_text[i%4]->dimensions().middle(-0.350 + 0.01 + 0.25 * i).fixedHeight(0.055*fzoom).screenTop(0.11);
break;
- case LayoutSinger::MIDDLE: // Band mode
+ case LayoutSinger::BAND: // Band mode
m_line_rank_text[i%4]->dimensions().right(0.30).fixedHeight(0.05*fzoom).screenTop(0.025 + 0.050 * i);
break;
case LayoutSinger::LEFT:
@@ -88,14 +88,14 @@ void LayoutSinger::drawScore(Position position) {
}
}
-void LayoutSinger::draw(double time, Position position) {
+void LayoutSinger::draw(double time, PositionMode position) {
// Draw notes and pitch waves (only when not in karaoke mode)
if (!config["game/karaoke_mode"].b()) {
switch(position) {
- case LayoutSinger::BOTTOM: // Fullscreen
+ case LayoutSinger::FULL: // Fullscreen
m_noteGraph.draw(time, m_database, NoteGraph::FULLSCREEN);
break;
- case LayoutSinger::MIDDLE: // Band mode
+ case LayoutSinger::BAND: // Band mode
m_noteGraph.draw(time, m_database, NoteGraph::TOP);
break;
case LayoutSinger::LEFT:
@@ -110,11 +110,11 @@ void LayoutSinger::draw(double time, Position position) {
double linespacing = 0.0;
Dimensions pos;
switch(position) {
- case LayoutSinger::BOTTOM: // Fullscreen
+ case LayoutSinger::FULL: // Fullscreen
pos.screenBottom(-0.1);
linespacing = 0.06;
break;
- case LayoutSinger::MIDDLE: // Band mode
+ case LayoutSinger::BAND: // Band mode
pos.center(-0.05);
linespacing = 0.04;
break;
@@ -143,7 +143,7 @@ void LayoutSinger::draw(double time, Position position) {
for (size_t i = 0; i < m_lyrics.size(); ++i, pos.move(0.0, linespacing)) {
pos.move(0.0, m_lyrics[i].extraspacing.get() * linespacing);
if (i == 0) m_lyrics[0].draw(m_theme->lyrics_now, time, pos);
- else if (i == 1 && position == LayoutSinger::BOTTOM) m_lyrics[1].draw(m_theme->lyrics_next, time, pos);
+ else if (i == 1 && position == LayoutSinger::FULL) m_lyrics[1].draw(m_theme->lyrics_next, time, pos);
}
}
}
diff --git a/game/layout_singer.hh b/game/layout_singer.hh
index 1529aea..a948f5b 100644
--- a/game/layout_singer.hh
+++ b/game/layout_singer.hh
@@ -49,15 +49,15 @@ class LyricRow {
class LayoutSinger {
public:
- enum Position {BOTTOM, MIDDLE, LEFT, RIGHT};
+ enum PositionMode {FULL, BAND, LEFT, RIGHT};
/// ThemeSing is optional if you want to use drawScore only
LayoutSinger(VocalTrack& vocal, Database& database, boost::shared_ptr<ThemeSing> theme = boost::shared_ptr<ThemeSing>());
~LayoutSinger();
void reset();
- void draw(double time, Position position = LayoutSinger::BOTTOM);
- void drawScore(Position position);
+ void draw(double time, PositionMode position = LayoutSinger::FULL);
+ void drawScore(PositionMode position);
double lyrics_begin() const;
- void hideLyrics(bool hide = true) { m_hideLyrics = hide; };
+ void hideLyrics(bool hide = true) { m_hideLyrics = hide; }
private:
VocalTrack& m_vocal;
NoteGraph m_noteGraph;
diff --git a/game/screen_players.cc b/game/screen_players.cc
index ae302f8..dd1d60e 100644
--- a/game/screen_players.cc
+++ b/game/screen_players.cc
@@ -175,6 +175,6 @@ void ScreenPlayers::draw() {
if (!video.empty() && config["graphic/video"].b()) m_video.reset(new Video(video, videoGap));
m_playing = music;
}
- m_layout_singer->drawScore(LayoutSinger::MIDDLE);
+ m_layout_singer->drawScore(LayoutSinger::BAND);
}
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index ff0f90c..bab75ba 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -460,12 +460,12 @@ void ScreenSing::draw() {
m_only_singers_alive = false;
// Singing only
} else if( m_instruments.empty() ) {
- m_layout_singer->draw(time, LayoutSinger::BOTTOM);
+ m_layout_singer->draw(time, LayoutSinger::FULL);
m_only_singers_alive = true;
// Band
} else {
m_only_singers_alive = !instrumentLayout(time);
- m_layout_singer->draw(time, m_only_singers_alive ? LayoutSinger::BOTTOM : LayoutSinger::MIDDLE);
+ m_layout_singer->draw(time, m_only_singers_alive ? LayoutSinger::FULL : LayoutSinger::BAND);
}
Song::Status status = m_song->status(time);
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:44:15
|
Author: Tapio Vierros <tap...@gm...>
Date: Sun Dec 18 14:49:40 2011 +0200
Prepare for release: hide keyboard icon in song browser.
---
game/screen_songs.cc | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/game/screen_songs.cc b/game/screen_songs.cc
index 9d5176b..fc0c86e 100644
--- a/game/screen_songs.cc
+++ b/game/screen_songs.cc
@@ -388,7 +388,7 @@ void ScreenSongs::drawInstruments(Dimensions const& dim, float alpha) const {
va.Color(c).TexCoord(getIconTex(5), 1.0f).Vertex(x, dim.y2());
va.Draw();
}
- {
+ /*{
// keyboard
float a = alpha * (have_keyboard ? 1.00f : 0.25f);
float m = !(typeFilter & 16);
@@ -401,17 +401,17 @@ void ScreenSongs::drawInstruments(Dimensions const& dim, float alpha) const {
va.Color(c).TexCoord(getIconTex(6), 0.0f).Vertex(x, dim.y1());
va.Color(c).TexCoord(getIconTex(6), 1.0f).Vertex(x, dim.y2());
va.Draw();
- }
+ }*/
{
// dancing
float a = alpha * (have_dance ? 1.00f : 0.25f);
float m = !(typeFilter & 1);
glutil::VertexArray va;
glmath::vec4 c(m * 1.0f, 1.0f, m * 1.0f, a);
- x = dim.x1()+5*xincr*(dim.x2()-dim.x1());
+ x = dim.x1()+4*xincr*(dim.x2()-dim.x1());
va.Color(c).TexCoord(getIconTex(6), 0.0f).Vertex(x, dim.y1());
va.Color(c).TexCoord(getIconTex(6), 1.0f).Vertex(x, dim.y2());
- x = dim.x1()+6*xincr*(dim.x2()-dim.x1());
+ x = dim.x1()+5*xincr*(dim.x2()-dim.x1());
va.Color(c).TexCoord(getIconTex(7), 0.0f).Vertex(x, dim.y1());
va.Color(c).TexCoord(getIconTex(7), 1.0f).Vertex(x, dim.y2());
va.Draw();
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:44:09
|
Author: Tapio Vierros <tap...@gm...>
Date: Thu Dec 15 19:22:32 2011 +0200
Instrument forcing in UI.
* Dynamically populate the config items with available controller presets.
* Use the config values when evaluating instrument forcing.
---
game/joystick.cc | 23 ++++++++++++++++++++++-
1 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/game/joystick.cc b/game/joystick.cc
index 29432ed..21285e1 100644
--- a/game/joystick.cc
+++ b/game/joystick.cc
@@ -333,8 +333,29 @@ void input::SDL::init() {
readControllers(g_instruments, getDefaultConfig(fs::path("/config/controllers.xml")));
readControllers(g_instruments, getConfigDir() / "controllers.xml");
std::map<unsigned int, input::Instrument> forced_type;
+ ConfigItem::StringList instruments = config["game/instruments"].sl();
+
+ // Populate controller forcing config items
+ ConfigItem& ci0 = config["game/instrument0"];
+ ConfigItem& ci1 = config["game/instrument1"];
+ ConfigItem& ci2 = config["game/instrument2"];
+ ConfigItem& ci3 = config["game/instrument3"];
+ int i = 0;
+ for (input::Instruments::const_iterator it = g_instruments.begin(); it != g_instruments.end(); ++it, ++i) {
+ // Add the enum
+ std::string title = it->second.description;
+ ci0.addEnum(title);
+ ci1.addEnum(title);
+ ci2.addEnum(title);
+ ci3.addEnum(title);
+ // Check for active items
+ if (i == ci0.i()-1) instruments.push_back("0:" + it->first);
+ if (i == ci1.i()-1) instruments.push_back("1:" + it->first);
+ if (i == ci2.i()-1) instruments.push_back("2:" + it->first);
+ if (i == ci3.i()-1) instruments.push_back("3:" + it->first);
+ }
- ConfigItem::StringList const& instruments = config["game/instruments"].sl();
+ // Check all forced instruments
for (ConfigItem::StringList::const_iterator it = instruments.begin(); it != instruments.end(); ++it) {
std::istringstream iss(*it);
unsigned sdl_id;
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:44:01
|
Author: Tapio Vierros <tap...@gm...>
Date: Thu Dec 15 18:54:48 2011 +0200
Added individual instrument forcing thingys to schema.
---
data/schema.xml | 32 ++++++++++++++++++++++++++++++++
1 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/data/schema.xml b/data/schema.xml
index 9f9a621..29b420c 100644
--- a/data/schema.xml
+++ b/data/schema.xml
@@ -63,6 +63,38 @@ to save the current settings to XML.
<short>Keyboard as keyboard</short>
<long>Enable keyboard as keyboard.</long>
</entry>
+ <entry name="game/instrument0" type="int" value="0">
+ <limits>
+ <enum>Auto</enum>
+ <!-- Options added dynamically from controllers.xml -->
+ </limits>
+ <short>Force controller A's type</short>
+ <long>Override autodetection and force the first controller to the given type.</long>
+ </entry>
+ <entry name="game/instrument1" type="int" value="0">
+ <limits>
+ <enum>Auto</enum>
+ <!-- Options added dynamically from controllers.xml -->
+ </limits>
+ <short>Force controller B's type</short>
+ <long>Override autodetection and force the second controller to the given type.</long>
+ </entry>
+ <entry name="game/instrument2" type="int" value="0">
+ <limits>
+ <enum>Auto</enum>
+ <!-- Options added dynamically from controllers.xml -->
+ </limits>
+ <short>Force controller C's type</short>
+ <long>Override autodetection and force the third controller to the given type.</long>
+ </entry>
+ <entry name="game/instrument3" type="int" value="0">
+ <limits>
+ <enum>Auto</enum>
+ <!-- Options added dynamically from controllers.xml -->
+ </limits>
+ <short>Force controller D's type</short>
+ <long>Override autodetection and force the fourth controller to the given type.</long>
+ </entry>
<entry name="game/instruments" type="string_list">
<!-- Should be SDL_ID:{GUITAR_GUITARHERO|GUITAR_GUITARHERO_XPLORER|GUITAR_ROCKBAND_PS3|GUITAR_ROCKBAND_XB360|DRUMS_GUITARHERO|DRUMS_ROCKBAND_PS3|DRUMS_ROCKBAND_XB360|DRUMS_MIDI|DANCEPAD_GENERIC|DANCEPAD_TIGERGAME|DANCEPAD_2TECH}
example:
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:43:58
|
Author: Tapio Vierros <tap...@gm...>
Date: Thu Dec 15 18:54:08 2011 +0200
Added a function to dynamically add enums to a ConfigItem.
---
game/configuration.cc | 8 ++++++++
game/configuration.hh | 1 +
2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/game/configuration.cc b/game/configuration.cc
index 3f6144d..de92d67 100644
--- a/game/configuration.cc
+++ b/game/configuration.cc
@@ -144,6 +144,14 @@ namespace {
}
}
+void ConfigItem::addEnum(std::string name) {
+ verifyType("int");
+ m_enums.push_back(name);
+ m_min = 0;
+ m_max = int(m_enums.size() - 1);
+ m_step = 1;
+}
+
template <typename T> void ConfigItem::updateNumeric(xmlpp::Element& elem, int mode) {
xmlpp::NodeSet ns = elem.find("limits");
if (!ns.empty()) setLimits<T>(dynamic_cast<xmlpp::Element&>(*ns[0]), m_min, m_max, m_step);
diff --git a/game/configuration.hh b/game/configuration.hh
index 82f2e6e..93278f8 100644
--- a/game/configuration.hh
+++ b/game/configuration.hh
@@ -37,6 +37,7 @@ class ConfigItem {
std::string getValue() const; ///< Get a human-readable representation of the current value
std::string const& getShortDesc() const { return m_shortDesc; } ///< get the short description for this ConfigItem
std::string const& getLongDesc() const { return m_longDesc; } ///< get the long description for this ConfigItem
+ void addEnum(std::string name); ///< Dynamically adds an enum to all values
private:
template <typename T> void updateNumeric(xmlpp::Element& elem, int mode); ///< Used internally for loading XML
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:43:52
|
Author: Tapio Vierros <tap...@gm...>
Date: Tue Nov 22 21:25:26 2011 +0200
Fixed Synth.
---
game/audio.cc | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 3484c8c..8cd85f7 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -279,7 +279,7 @@ struct Synth {
if (it == m_notes.end() || it->type == Note::SLEEP || it->begin > position) { phase = 0.0; return; }
int note = it->note % 12;
double d = (note + 1) / 13.0;
- double freq = MusicalScale().getNoteFreq(note + 12);
+ double freq = MusicalScale().getNoteFreq(note + 4 * 12);
double value = 0.0;
// Synthesize tones
for (size_t i = 0, iend = mixbuf.size(); i != iend; ++i) {
|