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: Lasse Kärkkäi. <tr...@us...> - 2009-07-15 04:01:30
|
Module: performous
Branch: master
Commit: 254a4650453e1a5f8ff8ef25c739f1d6e5d551ca
Author: Lasse Karkkainen <tro...@tr...>
Date: Wed Jul 15 06:43:47 2009 +0300
Rewritten lyric hack part of INI/MID song parser.
Support slide notes added for parser, notegraph and note.
Scoring and Note::diff need to be rewritten to make slides work properly.
---
game/notegraph.cc | 39 ++++++++++++++++++++++-----------------
game/notes.cc | 4 ++--
game/notes.hh | 8 ++++----
game/songparser-ini.cc | 45 +++++++++++++++++++++++++++++----------------
4 files changed, 57 insertions(+), 39 deletions(-)
diff --git a/game/notegraph.cc b/game/notegraph.cc
index 5cc0999..d82dc91 100644
--- a/game/notegraph.cc
+++ b/game/notegraph.cc
@@ -19,25 +19,29 @@ void NoteGraph::reset() {
}
namespace {
- void drawNotebar(Texture const& texture, double x, double y, double w, double h) {
+ void drawNotebar(Texture const& texture, double x, double ybeg, double yend, double w, double h) {
UseTexture tblock(texture);
glutil::Begin block(GL_TRIANGLE_STRIP);
- glTexCoord2f(0.0f, 0.0f); glVertex2f(x, y);
- glTexCoord2f(0.0f, 1.0f); glVertex2f(x, y + h);
+ glTexCoord2f(0.0f, 0.0f); glVertex2f(x, ybeg);
+ glTexCoord2f(0.0f, 1.0f); glVertex2f(x, ybeg + h);
if (w >= 2.0 * h) {
- glTexCoord2f(0.5f, 0.0f); glVertex2f(x + h, y);
- glTexCoord2f(0.5f, 1.0f); glVertex2f(x + h, y + h);
- glTexCoord2f(0.5f, 0.0f); glVertex2f(x + w - h, y);
- glTexCoord2f(0.5f, 1.0f); glVertex2f(x + w - h, y + h);
+ double tmp = h / w;
+ double y1 = (1.0 - tmp) * ybeg + tmp * yend;
+ double y2 = tmp * ybeg + (1.0 - tmp) * yend;
+ glTexCoord2f(0.5f, 0.0f); glVertex2f(x + h, y1);
+ glTexCoord2f(0.5f, 1.0f); glVertex2f(x + h, y1 + h);
+ glTexCoord2f(0.5f, 0.0f); glVertex2f(x + w - h, y2);
+ glTexCoord2f(0.5f, 1.0f); glVertex2f(x + w - h, y2 + h);
} else {
+ double ymid = 0.5 * (ybeg + yend);
float crop = 0.25f * w / h;
- glTexCoord2f(crop, 0.0f); glVertex2f(x + 0.5 * w, y);
- glTexCoord2f(crop, 1.0f); glVertex2f(x + 0.5 * w, y + h);
- glTexCoord2f(1.0f - crop, 0.0f); glVertex2f(x + 0.5 * w, y);
- glTexCoord2f(1.0f - crop, 1.0f); glVertex2f(x + 0.5 * w, y + h);
+ glTexCoord2f(crop, 0.0f); glVertex2f(x + 0.5 * w, ymid);
+ glTexCoord2f(crop, 1.0f); glVertex2f(x + 0.5 * w, ymid + h);
+ glTexCoord2f(1.0f - crop, 0.0f); glVertex2f(x + 0.5 * w, ymid);
+ glTexCoord2f(1.0f - crop, 1.0f); glVertex2f(x + 0.5 * w, ymid + h);
}
- glTexCoord2f(1.0f, 0.0f); glVertex2f(x + w, y);
- glTexCoord2f(1.0f, 1.0f); glVertex2f(x + w, y + h);
+ glTexCoord2f(1.0f, 0.0f); glVertex2f(x + w, yend);
+ glTexCoord2f(1.0f, 1.0f); glVertex2f(x + w, yend + h);
}
}
@@ -96,7 +100,7 @@ void NoteGraph::drawNotes() {
Texture* t1;
Texture* t2;
switch (it->type) {
- case Note::NORMAL: t1 = &m_notebar; t2 = &m_notebar_hl; break;
+ case Note::NORMAL: case Note::SLIDE: t1 = &m_notebar; t2 = &m_notebar_hl; break;
case Note::GOLDEN: t1 = &m_notebargold; t2 = &m_notebargold_hl; break;
case Note::FREESTYLE: // Freestyle notes use custom handling
{
@@ -113,13 +117,14 @@ void NoteGraph::drawNotes() {
default: throw std::logic_error("Unknown note type: don't know how to render");
}
double x = m_baseX + it->begin * pixUnit + m_noteUnit; // left x coordinate: begin minus border (side borders -noteUnit wide)
- double y = m_baseY + (it->note + 1) * m_noteUnit; // top y coordinate (on the one higher note line)
+ double ybeg = m_baseY + (it->notePrev + 1) * m_noteUnit; // top y coordinate (on the one higher note line)
+ double yend = m_baseY + (it->note + 1) * m_noteUnit; // top y coordinate (on the one higher note line)
double w = (it->end - it->begin) * pixUnit - m_noteUnit * 2.0; // width: including borders on both sides
double h = -m_noteUnit * 2.0; // height: 0.5 border + 1.0 bar + 0.5 border = 2.0
- drawNotebar(*t1, x, y, w, h);
+ drawNotebar(*t1, x, ybeg, yend, w, h);
if (alpha > 0.0) {
glColor4f(1.0f, 1.0f, 1.0f, alpha * m_notealpha);
- drawNotebar(*t2, x, y, w, h);
+ drawNotebar(*t2, x, ybeg, yend, w, h);
glColor4f(1.0f, 1.0f, 1.0f, m_notealpha);
}
}
diff --git a/game/notes.cc b/game/notes.cc
index 9833315..90b1594 100644
--- a/game/notes.cc
+++ b/game/notes.cc
@@ -54,7 +54,7 @@ double MusicalScale::getNoteOffset(double freq) const {
return 12.0 * std::log(frac) / std::log(2.0);
}
-Note::Note(): begin(getNaN()), end(getNaN()), power(getNaN()), type(NORMAL), note() {}
+Note::Note(): begin(getNaN()), end(getNaN()), power(getNaN()), type(NORMAL), note(), notePrev() {}
double Note::diff(double note, double n) { return remainder(n - note, 12.0); }
double Note::maxScore() const { return scoreMultiplier(0.0) * (end - begin); }
@@ -69,7 +69,7 @@ double Note::scoreMultiplier(double error) const {
double max = 0.0;
switch (type) {
case FREESTYLE: power += 1.0; return 1.0;
- case NORMAL: max = 1.0; break;
+ case NORMAL: case SLIDE: max = 1.0; break;
case GOLDEN: max = 2.0; break;
case SLEEP: break;
}
diff --git a/game/notes.hh b/game/notes.hh
index bb402f8..7a486d4 100644
--- a/game/notes.hh
+++ b/game/notes.hh
@@ -30,14 +30,15 @@ class MusicalScale {
/// note read from songfile
struct Note {
+ Note();
double begin, ///< begin time
end; ///< end time
/// power of note
mutable double power;
/// note type
- enum Type { FREESTYLE = 'F', NORMAL = ':', GOLDEN = '*', SLEEP = '-'} type;
- /// note
- int note;
+ enum Type { FREESTYLE = 'F', NORMAL = ':', GOLDEN = '*', SLIDE = '+', SLEEP = '-'} type;
+ int note; ///< MIDI pitch of the note (at the end for slide notes)
+ int notePrev; ///< MIDI pitch of the previous note (should be same as note for everything but SLIDE)
/// lyrics syllable for that note
std::string syllable;
/// Difference of n from note
@@ -48,7 +49,6 @@ struct Note {
double maxScore() const;
/// score when singing
double score(double freq, double b, double e) const;
- Note();
static bool ltBegin(Note const& a, Note const& b) { return a.begin < b.begin; }
static bool ltEnd(Note const& a, Note const& b) { return a.end < b.end; }
private:
diff --git a/game/songparser-ini.cc b/game/songparser-ini.cc
index 40112ec..05a495b 100644
--- a/game/songparser-ini.cc
+++ b/game/songparser-ini.cc
@@ -48,24 +48,37 @@ void SongParser::iniParse() {
Note n;
n.begin = midi.get_seconds(it2->begin);
n.end = midi.get_seconds(it2->end);
- n.note = it2->note;
+ n.notePrev = n.note = it2->note;
n.type = n.note > 100 ? Note::SLEEP : Note::NORMAL;
n.syllable = it2->lyric;
- if (!n.syllable.empty()) {
- switch (*n.syllable.rbegin()) {
- case '#': {
- n.type = Note::FREESTYLE;
- n.syllable.erase(n.syllable.size()-1);
- if( *n.syllable.rbegin() != '-' ) n.syllable += " ";
- break;
- }
- case '-': eraseLast(n.syllable, '-'); break;
- case '+': if (!s.notes.empty()) eraseLast(s.notes.back().syllable); *n.syllable.rbegin() = '~'; break;
- default: n.syllable += " "; break;
+ std::string& syl = n.syllable;
+ if (n.type != Note::SLEEP) {
+ if (!syl.empty()) {
+ bool erase = false;
+ // Examine note styles (specified by the last character of the syllable)
+ {
+ char& ch = *syl.rbegin();
+ if (ch == '#') { n.type = Note::FREESTYLE; erase = true; }
+ if (ch == '^') { n.type = Note::GOLDEN; erase = true; }
+ if (ch == '+') { n.type = Note::SLIDE; ch = '~'; }
+ }
+ if (erase) syl.erase(syl.size() - 1);
+ // Add spaces between words, remove hyphens
+ {
+ char ch = *syl.rbegin();
+ if (ch == '-') syl.erase(syl.size() - 1);
+ else if (ch != '~') syl += ' ';
+ }
+ }
+ // Special processing for slides (which depend on the previous note)
+ if (n.type == Note::SLIDE) {
+ Notes::reverse_iterator prev = s.notes.rbegin();
+ while (prev != s.notes.rend() && prev->type == Note::SLEEP) ++prev;
+ if (prev == s.notes.rend()) throw std::runtime_error("The song begins with a slide note");
+ eraseLast(prev->syllable); // Erase the space if there is any
+ n.notePrev = prev->note;
}
m_maxScore += n.maxScore();
- }
- if (n.type == Note::NORMAL || n.type == Note::FREESTYLE) {
s.noteMin = std::min(s.noteMin, n.note);
s.noteMax = std::max(s.noteMax, n.note);
s.notes.push_back(n);
@@ -76,14 +89,14 @@ void SongParser::iniParse() {
}
if (!s.notes.empty()) break;
}
- if (s.notes.empty()) {
+ /*if (s.notes.empty()) {
Note n;
n.begin = 30.0;
n.end = 31.0;
n.syllable = "TODO";
s.noteMin = s.noteMax = n.note = 60;
s.notes.push_back(n);
- }
+ }*/
}
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-14 11:20:46
|
Module: performous Branch: 0.3 Commit: 19270594d904f74e09ce74539c29f38f0c9e6b73 Author: Vincent Le Ligeour <yo...@us...> Date: Tue Jul 14 12:31:32 2009 +0200 Fixed shell script helper to correctly parse parameters --- cmake/performous.sh.cmake | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/cmake/performous.sh.cmake b/cmake/performous.sh.cmake index fa386cc..7326c21 100644 --- a/cmake/performous.sh.cmake +++ b/cmake/performous.sh.cmake @@ -1,4 +1,4 @@ #!/bin/sh -env PERFORMOUS_DATA_DIR='@CMAKE_INSTALL_PREFIX@/@SHARE_INSTALL@' PLUGIN_PATH='@PERFORMOUS_PLUGIN_PATH@' '@PERFORMOUS_EXECUTABLE@' $@ +env PERFORMOUS_DATA_DIR='@CMAKE_INSTALL_PREFIX@/@SHARE_INSTALL@' PLUGIN_PATH='@PERFORMOUS_PLUGIN_PATH@' '@PERFORMOUS_EXECUTABLE@' "$@" |
|
From: Yoda-JM <yo...@us...> - 2009-07-14 10:32:25
|
Module: performous Branch: master Commit: 3cc276e330bb01373780f6700b64ab5ce3e4ebb0 Author: Vincent Le Ligeour <yo...@us...> Date: Tue Jul 14 12:31:32 2009 +0200 Fixed shell script helper to correctly parse parameters --- cmake/performous.sh.cmake | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/cmake/performous.sh.cmake b/cmake/performous.sh.cmake index fa386cc..7326c21 100644 --- a/cmake/performous.sh.cmake +++ b/cmake/performous.sh.cmake @@ -1,4 +1,4 @@ #!/bin/sh -env PERFORMOUS_DATA_DIR='@CMAKE_INSTALL_PREFIX@/@SHARE_INSTALL@' PLUGIN_PATH='@PERFORMOUS_PLUGIN_PATH@' '@PERFORMOUS_EXECUTABLE@' $@ +env PERFORMOUS_DATA_DIR='@CMAKE_INSTALL_PREFIX@/@SHARE_INSTALL@' PLUGIN_PATH='@PERFORMOUS_PLUGIN_PATH@' '@PERFORMOUS_EXECUTABLE@' "$@" |
|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-13 20:54:47
|
Module: performous
Branch: master
Commit: ce49ecb0ecd8a95c00f69e3a76fcba8d9010e47e
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jul 13 23:50:28 2009 +0300
Update CMakeLists.txts to indicate that CMake 2.6 is required (they didn't work with 2.4 anyway) and remove old compatibility options.
---
CMakeLists.txt | 8 ++------
game/CMakeLists.txt | 6 +-----
tools/CMakeLists.txt | 6 +-----
3 files changed, 4 insertions(+), 16 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1969728..6214ffc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
project(Performous CXX)
-cmake_minimum_required(VERSION 2.4)
+cmake_minimum_required(VERSION 2.6)
set(PROJECT_VERSION "0.3.2+")
# Avoid source tree pollution
@@ -7,11 +7,7 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR "In-source builds are not permitted. Make a separate folder for building:\nmkdir build; cd build; cmake ..\nBefore that, remove the files already created:\nrm -rf CMakeCache.txt CMakeFiles")
endif(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
-if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 5)
- include("${CMAKE_SOURCE_DIR}/cmake/performous-packaging.cmake")
-else(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 5)
- message("Automatic packaging support disabled (CMake 2.6 or later required)")
-endif(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 5)
+include("${CMAKE_SOURCE_DIR}/cmake/performous-packaging.cmake")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt
index c9584e9..848567e 100644
--- a/game/CMakeLists.txt
+++ b/game/CMakeLists.txt
@@ -1,8 +1,4 @@
-cmake_minimum_required(VERSION 2.4)
-
-if(COMMAND cmake_policy)
- cmake_policy(SET CMP0003 NEW)
-endif(COMMAND cmake_policy)
+cmake_minimum_required(VERSION 2.6)
FILE(GLOB SOURCE_FILES "*.cc")
FILE(GLOB HEADER_FILES "*.hh")
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 5244b0d..f9d7c35 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -1,8 +1,4 @@
-cmake_minimum_required(VERSION 2.4)
-
-if(COMMAND cmake_policy)
- cmake_policy(SET CMP0003 NEW)
-endif(COMMAND cmake_policy)
+cmake_minimum_required(VERSION 2.6)
# Libraries
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-13 20:54:46
|
Module: performous
Branch: 0.3
Commit: 4f8e35ff235bc513b8cfcde0208f42c556d34960
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jul 13 23:50:28 2009 +0300
Update CMakeLists.txts to indicate that CMake 2.6 is required (they didn't work with 2.4 anyway) and remove old compatibility options.
---
CMakeLists.txt | 8 ++------
game/CMakeLists.txt | 6 +-----
tools/CMakeLists.txt | 6 +-----
3 files changed, 4 insertions(+), 16 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0690fc4..d54a8c7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
project(Performous CXX)
-cmake_minimum_required(VERSION 2.4)
+cmake_minimum_required(VERSION 2.6)
set(PROJECT_VERSION "0.3.2")
# Avoid source tree pollution
@@ -7,11 +7,7 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR "In-source builds are not permitted. Make a separate folder for building:\nmkdir build; cd build; cmake ..\nBefore that, remove the files already created:\nrm -rf CMakeCache.txt CMakeFiles")
endif(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
-if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 5)
- include("${CMAKE_SOURCE_DIR}/cmake/performous-packaging.cmake")
-else(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 5)
- message("Automatic packaging support disabled (CMake 2.6 or later required)")
-endif(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 5)
+include("${CMAKE_SOURCE_DIR}/cmake/performous-packaging.cmake")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt
index c9584e9..848567e 100644
--- a/game/CMakeLists.txt
+++ b/game/CMakeLists.txt
@@ -1,8 +1,4 @@
-cmake_minimum_required(VERSION 2.4)
-
-if(COMMAND cmake_policy)
- cmake_policy(SET CMP0003 NEW)
-endif(COMMAND cmake_policy)
+cmake_minimum_required(VERSION 2.6)
FILE(GLOB SOURCE_FILES "*.cc")
FILE(GLOB HEADER_FILES "*.hh")
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 5244b0d..f9d7c35 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -1,8 +1,4 @@
-cmake_minimum_required(VERSION 2.4)
-
-if(COMMAND cmake_policy)
- cmake_policy(SET CMP0003 NEW)
-endif(COMMAND cmake_policy)
+cmake_minimum_required(VERSION 2.6)
# Libraries
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-13 20:45:15
|
Module: performous Branch: 0.3 Commit: 4156e2506912d66edf02588166297d8ceadc1a27 Author: Lasse Karkkainen <tro...@tr...> Date: Mon Jul 13 23:44:58 2009 +0300 Fix typo. --- CMakeLists.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3393d94..0690fc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ project(Performous CXX) cmake_minimum_required(VERSION 2.4) -set(PROJECT_VERSION "0.3.2) +set(PROJECT_VERSION "0.3.2") # Avoid source tree pollution if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) |
|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-13 20:35:53
|
Module: performous Branch: 0.3 Commit: 0448208e490ae75ff0fd6603504a408cc8286a97 Author: Lasse Karkkainen <tro...@tr...> Date: Mon Jul 13 23:34:29 2009 +0300 Change version number to 0.3.2. --- CMakeLists.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8be78fa..3393d94 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ project(Performous CXX) cmake_minimum_required(VERSION 2.4) -set(PROJECT_VERSION "0.3.1+") +set(PROJECT_VERSION "0.3.2) # Avoid source tree pollution if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) |
|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-13 20:35:53
|
Module: performous Branch: master Commit: 2dac4aec0d1f9d03d7c2a893a37548ae7522516c Author: Lasse Karkkainen <tro...@tr...> Date: Mon Jul 13 23:35:11 2009 +0300 Change version number to 0.3.2+. --- CMakeLists.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5742833..1969728 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ project(Performous CXX) cmake_minimum_required(VERSION 2.4) -set(PROJECT_VERSION "0.3.1+") +set(PROJECT_VERSION "0.3.2+") # Avoid source tree pollution if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) |
|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-13 20:31:02
|
Module: performous
Branch: 0.3
Commit: 31096f2b7f3461c358d1a9b0f2f8fcf61f37c9e6
Author: Vincent Le Ligeour <yo...@us...>
Date: Mon Jul 13 17:45:20 2009 +0200
Fixed one everlonging ffmpeg problem
---
game/ffmpeg.cc | 18 +++++++++++++++---
1 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/game/ffmpeg.cc b/game/ffmpeg.cc
index 31f49cd..44cc0a9 100644
--- a/game/ffmpeg.cc
+++ b/game/ffmpeg.cc
@@ -210,6 +210,18 @@ void FFmpeg::decodeNextFrame() {
AVFrame* operator->() { return m_frame; }
} videoFrame;
+ class AudioBuffer {
+ public:
+ AudioBuffer(size_t _size): m_buffer((int16_t*)av_malloc(_size*sizeof(int16_t))) {
+ if (!m_buffer) throw std::runtime_error("Unable to allocate AudioBuffer");
+ }
+ ~AudioBuffer() { av_free(m_buffer); }
+ operator int16_t*() { return m_buffer; }
+ int16_t* operator->() { return m_buffer; }
+ private:
+ int16_t* m_buffer;
+ };
+
int frameFinished=0;
while (!frameFinished) {
ReadFramePacket packet(pFormatCtx);
@@ -244,9 +256,9 @@ void FFmpeg::decodeNextFrame() {
while (packetSize) {
if (packetSize < 0) throw std::logic_error("negative audio packet size?!");
if (m_quit || m_seekTarget == m_seekTarget) return;
- std::vector<int16_t> audioFrames(AVCODEC_MAX_AUDIO_FRAME_SIZE);
+ AudioBuffer audioFrames(AVCODEC_MAX_AUDIO_FRAME_SIZE);
int outsize = AVCODEC_MAX_AUDIO_FRAME_SIZE*sizeof(int16_t);
- int decodeSize = avcodec_decode_audio2(pAudioCodecCtx, &audioFrames[0], &outsize, packetData, packetSize);
+ int decodeSize = avcodec_decode_audio2(pAudioCodecCtx, audioFrames, &outsize, packetData, packetSize);
// Handle special cases
if (decodeSize == 0) break;
if (outsize == 0) continue;
@@ -257,7 +269,7 @@ void FFmpeg::decodeNextFrame() {
// Convert outsize from bytes into number of frames (samples)
outsize /= sizeof(int16_t) * pAudioCodecCtx->channels;
std::vector<int16_t> resampled(AVCODEC_MAX_AUDIO_FRAME_SIZE);
- int frames = audio_resample(pResampleCtx, &resampled[0], &audioFrames[0], outsize);
+ int frames = audio_resample(pResampleCtx, &resampled[0], audioFrames, outsize);
// Construct AudioFrame and add it to the queue
AudioFrame* tmp = new AudioFrame();
std::copy(resampled.begin(), resampled.begin() + frames * AUDIO_CHANNELS, std::back_inserter(tmp->data));
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-13 20:28:12
|
Module: performous
Branch: 0.3
Commit: 57625830d7751e52cb8f64fd753ec262069b714f
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jul 13 03:52:21 2009 +0300
Added glutil.hh and used it in a few places.
---
game/glutil.hh | 16 ++++++++++++++++
game/notegraph.cc | 3 +--
game/screen.hh | 8 ++++----
game/screen_sing.cc | 5 ++---
game/surface.cc | 1 -
game/surface.hh | 5 ++---
game/video_driver.cc | 2 +-
7 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/game/glutil.hh b/game/glutil.hh
new file mode 100644
index 0000000..96c9541
--- /dev/null
+++ b/game/glutil.hh
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <GL/glew.h>
+
+namespace glutil {
+ struct PushMatrix {
+ PushMatrix() { glPushMatrix(); }
+ ~PushMatrix() { glPopMatrix(); }
+ };
+
+ struct Begin {
+ Begin(GLint mode) { glBegin(mode); }
+ ~Begin() { glEnd(); }
+ };
+}
+
diff --git a/game/notegraph.cc b/game/notegraph.cc
index 7cb37a5..5cc0999 100644
--- a/game/notegraph.cc
+++ b/game/notegraph.cc
@@ -21,7 +21,7 @@ void NoteGraph::reset() {
namespace {
void drawNotebar(Texture const& texture, double x, double y, double w, double h) {
UseTexture tblock(texture);
- glBegin(GL_TRIANGLE_STRIP);
+ glutil::Begin block(GL_TRIANGLE_STRIP);
glTexCoord2f(0.0f, 0.0f); glVertex2f(x, y);
glTexCoord2f(0.0f, 1.0f); glVertex2f(x, y + h);
if (w >= 2.0 * h) {
@@ -38,7 +38,6 @@ namespace {
}
glTexCoord2f(1.0f, 0.0f); glVertex2f(x + w, y);
glTexCoord2f(1.0f, 1.0f); glVertex2f(x + w, y + h);
- glEnd();
}
}
diff --git a/game/screen.hh b/game/screen.hh
index 1ce58c5..328ddfc 100644
--- a/game/screen.hh
+++ b/game/screen.hh
@@ -1,12 +1,12 @@
#pragma once
-#include <boost/ptr_container/ptr_map.hpp>
-#include <boost/scoped_ptr.hpp>
-#include "singleton.hh"
#include "audio.hh"
+#include "glutil.hh"
#include "record.hh"
+#include "singleton.hh"
#include "songs.hh"
-#include <GL/glew.h>
+#include <boost/ptr_container/ptr_map.hpp>
+#include <boost/scoped_ptr.hpp>
#include <SDL.h>
#include <iostream>
#include <string>
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index c2a6b01..1536b1d 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -105,12 +105,11 @@ namespace {
void fillBG() {
Dimensions dim(arMin);
dim.fixedWidth(1.0);
- glBegin(GL_QUADS);
+ glutil::Begin block(GL_QUADS);
glVertex2f(dim.x1(), dim.y1());
glVertex2f(dim.x2(), dim.y1());
glVertex2f(dim.x2(), dim.y2());
glVertex2f(dim.x1(), dim.y2());
- glEnd();
}
}
@@ -249,7 +248,7 @@ ScoreWindow::ScoreWindow(Engine& e):
}
void ScoreWindow::draw() {
- struct PushMatrixBlock { PushMatrixBlock() { glPushMatrix(); } ~PushMatrixBlock() { glPopMatrix(); } } b;
+ glutil::PushMatrix block;
glTranslatef(0.0, m_pos.get(), 0.0);
m_bg.draw();
const double spacing = 0.1 + 0.1 / m_players.size();
diff --git a/game/surface.cc b/game/surface.cc
index c172301..3d59458 100644
--- a/game/surface.cc
+++ b/game/surface.cc
@@ -3,7 +3,6 @@
#include "fs.hh"
#include "configuration.hh"
#include "video_driver.hh"
-#include <GL/glu.h>
#include <Magick++.h>
#include <boost/bind.hpp>
#include <fstream>
diff --git a/game/surface.hh b/game/surface.hh
index 3d2d1eb..92e6b64 100644
--- a/game/surface.hh
+++ b/game/surface.hh
@@ -1,6 +1,6 @@
#pragma once
-#include <GL/glew.h>
+#include "glutil.hh"
#include <stdexcept>
#include <string>
#include <boost/noncopyable.hpp>
@@ -127,12 +127,11 @@ class UseTexture: boost::noncopyable {
template <GLenum Type> void OpenGLTexture<Type>::draw(Dimensions const& dim, TexCoords const& tex) const {
UseTexture texture(*this);
- glBegin(GL_QUADS);
+ glutil::Begin block(GL_QUADS);
glTexCoord2f(tex.x1, tex.y1); glVertex2f(dim.x1(), dim.y1());
glTexCoord2f(tex.x2, tex.y1); glVertex2f(dim.x2(), dim.y1());
glTexCoord2f(tex.x2, tex.y2); glVertex2f(dim.x2(), dim.y2());
glTexCoord2f(tex.x1, tex.y2); glVertex2f(dim.x1(), dim.y2());
- glEnd();
}
template <GLenum Type> void OpenGLTexture<Type>::drawCropped(Dimensions const& orig, TexCoords const& tex) const {
diff --git a/game/video_driver.cc b/game/video_driver.cc
index 072e7a0..2a1e0e9 100644
--- a/game/video_driver.cc
+++ b/game/video_driver.cc
@@ -1,9 +1,9 @@
#include "video_driver.hh"
#include "config.hh"
+#include "glutil.hh"
#include "screen.hh"
#include "util.hh"
-#include <GL/glew.h>
#include <SDL.h>
unsigned s_width;
|
|
From: Yoda-JM <yo...@us...> - 2009-07-13 19:35:26
|
Module: performous
Branch: master
Commit: 53f6eda21f75424f9d424c10b5384519b05aabb0
Author: Vincent Le Ligeour <yo...@us...>
Date: Mon Jul 13 21:34:47 2009 +0200
Added some multiple audio sync stuffs
---
game/audio.cc | 22 +++++++++++++++++++++-
game/audio.hh | 1 +
2 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 4abafaa..0773c59 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -11,7 +11,8 @@
#include <memory>
Audio::Audio():
- m_paused(false)
+ m_paused(false),
+ m_need_resync(false)
{}
void Audio::open(std::string const& pdev, std::size_t rate, std::size_t frames) {
@@ -32,6 +33,23 @@ void Audio::operator()(da::pcm_data& areas, da::settings const&) {
static double phase = 0.0;
std::fill(areas.m_buf, areas.m_buf + samples, 0.0f);
if (!m_paused) {
+ if(m_need_resync) {
+ /*
+ std::cout << "Audio need to be synched here" << std::endl;
+ // do a fast forward sync
+ double position = 0.0;
+ for (Streams::iterator it = m_streams.begin(); it != m_streams.end();) {
+ double tmp = it->mpeg.position();
+ if( tmp > position ) position = tmp;
+ ++it;
+ }
+ for (Streams::iterator it = m_streams.begin(); it != m_streams.end();) {
+ it->mpeg.seek(position);
+ ++it;
+ }
+ */
+ m_need_resync = false;
+ }
for (Streams::iterator it = m_streams.begin(); it != m_streams.end();) {
it->playmix(areas.m_buf, samples);
if (it->fade <= 0.0) { it = m_streams.erase(it); continue; }
@@ -82,6 +100,7 @@ void Audio::playMusic(std::vector<std::string> const& filenames, bool preview, d
m_streams.push_back(s);
}
if (!preview) m_paused = false;
+ m_need_resync = true;
}
void Audio::playMusic(std::string const& filename, bool preview, double fadeTime, double startPos) {
@@ -154,5 +173,6 @@ void Audio::seekPos(double pos) {
it->prebuffering = true;
}
m_paused = false;
+ m_need_resync = true;
}
diff --git a/game/audio.hh b/game/audio.hh
index 3378891..cabfe30 100644
--- a/game/audio.hh
+++ b/game/audio.hh
@@ -163,6 +163,7 @@ class Audio {
typedef boost::ptr_vector<Stream> Streams;
Streams m_streams;
bool m_paused;
+ bool m_need_resync;
Notes const* volatile m_notes;
da::settings m_rs;
boost::scoped_ptr<da::playback> m_playback;
|
|
From: Yoda-JM <yo...@us...> - 2009-07-13 16:41:16
|
Module: performous
Branch: master
Commit: 868547683ec759b4fc655e43c8fd5050f24c2b9b
Author: Vincent Le Ligeour <yo...@us...>
Date: Mon Jul 13 18:40:41 2009 +0200
Fixed ini scoring
---
game/songparser-ini.cc | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/game/songparser-ini.cc b/game/songparser-ini.cc
index 82cf8c5..40112ec 100644
--- a/game/songparser-ini.cc
+++ b/game/songparser-ini.cc
@@ -63,6 +63,7 @@ void SongParser::iniParse() {
case '+': if (!s.notes.empty()) eraseLast(s.notes.back().syllable); *n.syllable.rbegin() = '~'; break;
default: n.syllable += " "; break;
}
+ m_maxScore += n.maxScore();
}
if (n.type == Note::NORMAL || n.type == Note::FREESTYLE) {
s.noteMin = std::min(s.noteMin, n.note);
|
|
From: Yoda-JM <yo...@us...> - 2009-07-13 15:45:52
|
Module: performous
Branch: master
Commit: 80b922c376209bd1e40e98d593c851c9117c816d
Author: Vincent Le Ligeour <yo...@us...>
Date: Mon Jul 13 17:45:20 2009 +0200
Fixed one everlonging ffmpeg problem
---
game/ffmpeg.cc | 18 +++++++++++++++---
1 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/game/ffmpeg.cc b/game/ffmpeg.cc
index 31f49cd..44cc0a9 100644
--- a/game/ffmpeg.cc
+++ b/game/ffmpeg.cc
@@ -210,6 +210,18 @@ void FFmpeg::decodeNextFrame() {
AVFrame* operator->() { return m_frame; }
} videoFrame;
+ class AudioBuffer {
+ public:
+ AudioBuffer(size_t _size): m_buffer((int16_t*)av_malloc(_size*sizeof(int16_t))) {
+ if (!m_buffer) throw std::runtime_error("Unable to allocate AudioBuffer");
+ }
+ ~AudioBuffer() { av_free(m_buffer); }
+ operator int16_t*() { return m_buffer; }
+ int16_t* operator->() { return m_buffer; }
+ private:
+ int16_t* m_buffer;
+ };
+
int frameFinished=0;
while (!frameFinished) {
ReadFramePacket packet(pFormatCtx);
@@ -244,9 +256,9 @@ void FFmpeg::decodeNextFrame() {
while (packetSize) {
if (packetSize < 0) throw std::logic_error("negative audio packet size?!");
if (m_quit || m_seekTarget == m_seekTarget) return;
- std::vector<int16_t> audioFrames(AVCODEC_MAX_AUDIO_FRAME_SIZE);
+ AudioBuffer audioFrames(AVCODEC_MAX_AUDIO_FRAME_SIZE);
int outsize = AVCODEC_MAX_AUDIO_FRAME_SIZE*sizeof(int16_t);
- int decodeSize = avcodec_decode_audio2(pAudioCodecCtx, &audioFrames[0], &outsize, packetData, packetSize);
+ int decodeSize = avcodec_decode_audio2(pAudioCodecCtx, audioFrames, &outsize, packetData, packetSize);
// Handle special cases
if (decodeSize == 0) break;
if (outsize == 0) continue;
@@ -257,7 +269,7 @@ void FFmpeg::decodeNextFrame() {
// Convert outsize from bytes into number of frames (samples)
outsize /= sizeof(int16_t) * pAudioCodecCtx->channels;
std::vector<int16_t> resampled(AVCODEC_MAX_AUDIO_FRAME_SIZE);
- int frames = audio_resample(pResampleCtx, &resampled[0], &audioFrames[0], outsize);
+ int frames = audio_resample(pResampleCtx, &resampled[0], audioFrames, outsize);
// Construct AudioFrame and add it to the queue
AudioFrame* tmp = new AudioFrame();
std::copy(resampled.begin(), resampled.begin() + frames * AUDIO_CHANNELS, std::back_inserter(tmp->data));
|
|
From: Yoda-JM <yo...@us...> - 2009-07-13 10:56:21
|
Module: performous
Branch: master
Commit: dffd813685e3f6a6ea1d5cd1839616ca07453a56
Author: Vincent Le Ligeour <yo...@us...>
Date: Mon Jul 13 12:55:48 2009 +0200
Tried to fix seekeing
---
game/audio.cc | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 7db4e06..4abafaa 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -67,6 +67,7 @@ void Audio::operator()(da::pcm_data& areas, da::settings const&) {
void Audio::playMusic(std::vector<std::string> const& filenames, bool preview, double fadeTime, double startPos) {
if (!isOpen()) return;
// First construct the new stream
+ boost::recursive_mutex::scoped_lock l(m_mutex);
fadeout(fadeTime);
for(std::vector<std::string>::const_iterator it = filenames.begin() ; it != filenames.end() ; ++it ) {
std::auto_ptr<Stream> s;
@@ -78,7 +79,6 @@ void Audio::playMusic(std::vector<std::string> const& filenames, bool preview, d
std::cerr << "Error loading " << *it << " (" << e.what() << ")" << std::endl;
continue;
}
- boost::recursive_mutex::scoped_lock l(m_mutex);
m_streams.push_back(s);
}
if (!preview) m_paused = false;
|
|
From: Yoda-JM <yo...@us...> - 2009-07-13 10:42:02
|
Module: performous
Branch: master
Commit: a96b96c732eb6b6542237ae566fc5843b1cd4cc0
Author: Vincent Le Ligeour <yo...@us...>
Date: Mon Jul 13 12:41:32 2009 +0200
Fixed multi-track seeking
---
game/audio.cc | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index f289928..7db4e06 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -148,10 +148,11 @@ void Audio::seek(double offset) {
void Audio::seekPos(double pos) {
boost::recursive_mutex::scoped_lock l(m_mutex);
if (m_streams.empty()) return;
- Stream& s = m_streams.back();
- int position = clamp(pos, 0.0, s.mpeg.duration() - 1.0);
- s.mpeg.seek(position);
- s.prebuffering = true;
+ for (Streams::iterator it = m_streams.begin(); it != m_streams.end(); ++it) {
+ int position = clamp(pos, 0.0, it->mpeg.duration() - 1.0);
+ it->mpeg.seek(position);
+ it->prebuffering = true;
+ }
m_paused = false;
}
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-13 01:14:18
|
Module: performous Branch: master Commit: a880b5524b9bb829c26b1be745f3cc6e8c0c3e33 Author: Lasse Kärkkäinen <tronic+ndrm at trn.iki.fi> Date: Mon Jul 13 03:57:56 2009 +0300 Disable Silky Strings by default. --- CMakeLists.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e07f9c4..5742833 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ add_subdirectory(game) add_subdirectory(docs) option(ENABLE_TOOLS "Enable extra tools (e.g. Singstar ripper)" ON) -option(ENABLE_SILKYSTRINGS "Enable Silky Strings (Guitar Hero clone)" ON) +option(ENABLE_SILKYSTRINGS "Enable Silky Strings (Guitar Hero clone)" OFF) if (ENABLE_TOOLS) add_subdirectory(tools) |
|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-13 00:54:37
|
Module: performous
Branch: master
Commit: 0c92751f2722b90720ce77c701df6ce6e1ad2b3a
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jul 13 03:52:21 2009 +0300
Added glutil.hh and used it in a few places.
---
game/glutil.hh | 16 ++++++++++++++++
game/guitargraph.cc | 6 ++----
game/notegraph.cc | 3 +--
game/screen.hh | 8 ++++----
game/screen_sing.cc | 5 ++---
game/surface.cc | 1 -
game/surface.hh | 5 ++---
game/video_driver.cc | 2 +-
8 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/game/glutil.hh b/game/glutil.hh
new file mode 100644
index 0000000..96c9541
--- /dev/null
+++ b/game/glutil.hh
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <GL/glew.h>
+
+namespace glutil {
+ struct PushMatrix {
+ PushMatrix() { glPushMatrix(); }
+ ~PushMatrix() { glPopMatrix(); }
+ };
+
+ struct Begin {
+ Begin(GLint mode) { glBegin(mode); }
+ ~Begin() { glEnd(); }
+ };
+}
+
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index 45adcab..86a2273 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -4,18 +4,16 @@ GuitarGraph::GuitarGraph(Song const& song): m_song(song), m_neck("guitarneck.svg
void GuitarGraph::draw(double time) {
UseTexture tex(m_neck);
- glPushMatrix();
+ glutil::PushMatrix pmb;
glTranslatef(0.0f, 0.3f, 0.0f);
glRotatef(80.0f, 1.0f, 0.0f, 0.0f);
glScalef(0.1f, 0.1f, 0.1f);
- glBegin(GL_QUADS);
float ts = 12.0f;
float future = 3.0f;
+ glutil::Begin block(GL_QUADS);
glTexCoord2f(0.0f, -(time + future)); glColor4f(1.0f, 1.0f, 1.0f, 0.0f); glVertex2f(-2.5f, -future * ts);
glTexCoord2f(1.0f, -(time + future)); glColor4f(1.0f, 1.0f, 1.0f, 0.0f); glVertex2f(2.5f, -future * ts);
glTexCoord2f(1.0f, -(time + 0.0f)); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glVertex2f(2.5f, 0.0f * ts);
glTexCoord2f(0.0f, -(time + 0.0f)); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glVertex2f(-2.5f, 0.0f * ts);
- glEnd();
glColor3f(1.0f, 1.0f, 1.0f);
- glPopMatrix();
}
diff --git a/game/notegraph.cc b/game/notegraph.cc
index 7cb37a5..5cc0999 100644
--- a/game/notegraph.cc
+++ b/game/notegraph.cc
@@ -21,7 +21,7 @@ void NoteGraph::reset() {
namespace {
void drawNotebar(Texture const& texture, double x, double y, double w, double h) {
UseTexture tblock(texture);
- glBegin(GL_TRIANGLE_STRIP);
+ glutil::Begin block(GL_TRIANGLE_STRIP);
glTexCoord2f(0.0f, 0.0f); glVertex2f(x, y);
glTexCoord2f(0.0f, 1.0f); glVertex2f(x, y + h);
if (w >= 2.0 * h) {
@@ -38,7 +38,6 @@ namespace {
}
glTexCoord2f(1.0f, 0.0f); glVertex2f(x + w, y);
glTexCoord2f(1.0f, 1.0f); glVertex2f(x + w, y + h);
- glEnd();
}
}
diff --git a/game/screen.hh b/game/screen.hh
index 1ce58c5..328ddfc 100644
--- a/game/screen.hh
+++ b/game/screen.hh
@@ -1,12 +1,12 @@
#pragma once
-#include <boost/ptr_container/ptr_map.hpp>
-#include <boost/scoped_ptr.hpp>
-#include "singleton.hh"
#include "audio.hh"
+#include "glutil.hh"
#include "record.hh"
+#include "singleton.hh"
#include "songs.hh"
-#include <GL/glew.h>
+#include <boost/ptr_container/ptr_map.hpp>
+#include <boost/scoped_ptr.hpp>
#include <SDL.h>
#include <iostream>
#include <string>
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index 04ea5d2..e43dd19 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -106,12 +106,11 @@ namespace {
void fillBG() {
Dimensions dim(arMin);
dim.fixedWidth(1.0);
- glBegin(GL_QUADS);
+ glutil::Begin block(GL_QUADS);
glVertex2f(dim.x1(), dim.y1());
glVertex2f(dim.x2(), dim.y1());
glVertex2f(dim.x2(), dim.y2());
glVertex2f(dim.x1(), dim.y2());
- glEnd();
}
}
@@ -253,7 +252,7 @@ ScoreWindow::ScoreWindow(Engine& e):
}
void ScoreWindow::draw() {
- struct PushMatrixBlock { PushMatrixBlock() { glPushMatrix(); } ~PushMatrixBlock() { glPopMatrix(); } } b;
+ glutil::PushMatrix block;
glTranslatef(0.0, m_pos.get(), 0.0);
m_bg.draw();
const double spacing = 0.1 + 0.1 / m_players.size();
diff --git a/game/surface.cc b/game/surface.cc
index c172301..3d59458 100644
--- a/game/surface.cc
+++ b/game/surface.cc
@@ -3,7 +3,6 @@
#include "fs.hh"
#include "configuration.hh"
#include "video_driver.hh"
-#include <GL/glu.h>
#include <Magick++.h>
#include <boost/bind.hpp>
#include <fstream>
diff --git a/game/surface.hh b/game/surface.hh
index 3d2d1eb..92e6b64 100644
--- a/game/surface.hh
+++ b/game/surface.hh
@@ -1,6 +1,6 @@
#pragma once
-#include <GL/glew.h>
+#include "glutil.hh"
#include <stdexcept>
#include <string>
#include <boost/noncopyable.hpp>
@@ -127,12 +127,11 @@ class UseTexture: boost::noncopyable {
template <GLenum Type> void OpenGLTexture<Type>::draw(Dimensions const& dim, TexCoords const& tex) const {
UseTexture texture(*this);
- glBegin(GL_QUADS);
+ glutil::Begin block(GL_QUADS);
glTexCoord2f(tex.x1, tex.y1); glVertex2f(dim.x1(), dim.y1());
glTexCoord2f(tex.x2, tex.y1); glVertex2f(dim.x2(), dim.y1());
glTexCoord2f(tex.x2, tex.y2); glVertex2f(dim.x2(), dim.y2());
glTexCoord2f(tex.x1, tex.y2); glVertex2f(dim.x1(), dim.y2());
- glEnd();
}
template <GLenum Type> void OpenGLTexture<Type>::drawCropped(Dimensions const& orig, TexCoords const& tex) const {
diff --git a/game/video_driver.cc b/game/video_driver.cc
index 39dcb5e..63fcd71 100644
--- a/game/video_driver.cc
+++ b/game/video_driver.cc
@@ -1,10 +1,10 @@
#include "video_driver.hh"
#include "config.hh"
+#include "glutil.hh"
#include "screen.hh"
#include "util.hh"
#include "joystick.hh"
-#include <GL/glew.h>
#include <SDL.h>
unsigned s_width;
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-13 00:34:24
|
Module: performous
Branch: master
Commit: fc3581bbdaeff945ee3fe7eb823a516639e2af74
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jul 13 03:33:51 2009 +0300
Cleanup.
---
game/songparser-ini.cc | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/game/songparser-ini.cc b/game/songparser-ini.cc
index b5c5020..82cf8c5 100644
--- a/game/songparser-ini.cc
+++ b/game/songparser-ini.cc
@@ -80,6 +80,7 @@ void SongParser::iniParse() {
n.begin = 30.0;
n.end = 31.0;
n.syllable = "TODO";
+ s.noteMin = s.noteMax = n.note = 60;
s.notes.push_back(n);
}
}
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-13 00:34:17
|
Module: performous
Branch: master
Commit: 808a0f8cd3377223647b9382fb1fe7f26f535741
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jul 13 03:32:02 2009 +0300
Only load existing music files.
---
game/screen_sing.cc | 1 -
game/songparser-ini.cc | 14 ++++++++++----
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index 919828a..04ea5d2 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -15,7 +15,6 @@ namespace {
void ScreenSing::enter() {
Song& song = m_songs.current();
- std::cout << "DEBUG::::: " << song.music.size() << std::endl;
m_audio.playMusic(song.music);
theme.reset(new ThemeSing());
if (!song.background.empty()) {
diff --git a/game/songparser-ini.cc b/game/songparser-ini.cc
index 87f8aa9..b5c5020 100644
--- a/game/songparser-ini.cc
+++ b/game/songparser-ini.cc
@@ -1,5 +1,6 @@
#include "songparser.hh"
+#include <boost/filesystem.hpp>
#include "midifile.hh"
/// @file Functions used for parsing the UltraStar TXT song format
@@ -13,6 +14,10 @@ namespace {
void eraseLast(std::string& s, char ch = ' ') {
if (!s.empty() && *s.rbegin() == ch) s.erase(s.size() - 1);
}
+ void testAndAdd(Song& s, std::string const& filename) {
+ std::string f = s.path + filename;
+ if (boost::filesystem::exists(f)) s.music.push_back(f);
+ }
}
void SongParser::iniParse() {
@@ -30,13 +35,14 @@ void SongParser::iniParse() {
else if (key == "artist") s.artist = value;
}
if (s.title.empty() || s.artist.empty()) throw std::runtime_error("Required header fields missing");
- s.music.push_back(s.path + "song.ogg");
- s.music.push_back(s.path + "guitar.ogg");
+ testAndAdd(s, "song.ogg");
+ testAndAdd(s, "guitar.ogg");
+ testAndAdd(s, "rhythm.ogg");
+ testAndAdd(s, "drums.ogg");
+ testAndAdd(s, "vocals.ogg");
MidiFileParser midi(s.path + "/notes.mid");
for (MidiFileParser::TempoChanges::const_iterator it = midi.tempochanges.begin(); it != midi.tempochanges.end(); ++it) addBPM(it->miditime * 4, it->value);
for (MidiFileParser::Tracks::const_iterator it = midi.tracks.begin(); it != midi.tracks.end(); ++it) {
- if (it->name == "PART RHYTHM" || it->name == "PART BASS") s.music.push_back(s.path + "rhythm.ogg");
- if (it->name == "PART DRUMS") s.music.push_back(s.path + "drums.ogg");
if (it->name != "PART VOCALS") continue;
for (MidiFileParser::Lyrics::const_iterator it2 = it->lyrics.begin(); it2 != it->lyrics.end(); ++it2) {
Note n;
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-12 23:56:10
|
Module: performous
Branch: master
Commit: e005f7c0a6d849476f7c88e7bcf9c75e211bf3ff
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jul 13 02:03:50 2009 +0300
Optimize MIDI parser (about 100x faster now).
---
game/midifile.cc | 12 +++++++-----
1 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/game/midifile.cc b/game/midifile.cc
index 8acbc69..c6eabb7 100644
--- a/game/midifile.cc
+++ b/game/midifile.cc
@@ -4,6 +4,7 @@
#include <fstream>
#include <iomanip>
#include <stdexcept>
+#include <sstream>
#include <string>
#define MIDI_DEBUG_LEVEL 1
@@ -25,7 +26,11 @@ class MidiStream {
*
* @param file MidiFile to be read
*/
- MidiStream(std::string file);
+ MidiStream(std::string const& file) {
+ std::ifstream ifs(file.c_str());
+ f << ifs.rdbuf();
+ f.exceptions(std::ios::failbit);
+ }
std::string read_bytes(size_t bytes);
@@ -58,15 +63,12 @@ class MidiStream {
private:
- std::ifstream f;
+ std::stringstream f;
uint16_t read_uint16() { return f.get() << 8 | f.get(); }
uint32_t read_uint32() { return f.get() << 24 | f.get() << 16 | f.get() << 8 | f.get(); }
};
-
-MidiStream::MidiStream(std::string file): f(file.c_str()) { f.exceptions(std::ios::failbit); }
-
namespace { bool is_not_alpha(char c) { return (c < 'A' || c > 'Z') && (c < 'a' || c > 'z'); } }
MidiStream::Riff::Riff(MidiStream& ms): ms(ms), name(ms.read_bytes(4)), size(ms.read_uint32()), offset(0) {
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-12 23:56:00
|
Module: performous
Branch: master
Commit: 2a94db73642cccf20353fb20078b3c6ac7024239
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jul 13 02:55:01 2009 +0300
Guitar graph moved to separate class, now only used for guitar songs.
---
game/guitargraph.cc | 21 +++++++++++++++++++++
game/guitargraph.hh | 24 ++++++++++++++++++++++++
game/notegraph.hh | 5 +----
game/screen_sing.cc | 27 ++++++---------------------
game/screen_sing.hh | 6 +++---
5 files changed, 55 insertions(+), 28 deletions(-)
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
new file mode 100644
index 0000000..45adcab
--- /dev/null
+++ b/game/guitargraph.cc
@@ -0,0 +1,21 @@
+#include "guitargraph.hh"
+
+GuitarGraph::GuitarGraph(Song const& song): m_song(song), m_neck("guitarneck.svg") {}
+
+void GuitarGraph::draw(double time) {
+ UseTexture tex(m_neck);
+ glPushMatrix();
+ glTranslatef(0.0f, 0.3f, 0.0f);
+ glRotatef(80.0f, 1.0f, 0.0f, 0.0f);
+ glScalef(0.1f, 0.1f, 0.1f);
+ glBegin(GL_QUADS);
+ float ts = 12.0f;
+ float future = 3.0f;
+ glTexCoord2f(0.0f, -(time + future)); glColor4f(1.0f, 1.0f, 1.0f, 0.0f); glVertex2f(-2.5f, -future * ts);
+ glTexCoord2f(1.0f, -(time + future)); glColor4f(1.0f, 1.0f, 1.0f, 0.0f); glVertex2f(2.5f, -future * ts);
+ glTexCoord2f(1.0f, -(time + 0.0f)); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glVertex2f(2.5f, 0.0f * ts);
+ glTexCoord2f(0.0f, -(time + 0.0f)); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glVertex2f(-2.5f, 0.0f * ts);
+ glEnd();
+ glColor3f(1.0f, 1.0f, 1.0f);
+ glPopMatrix();
+}
diff --git a/game/guitargraph.hh b/game/guitargraph.hh
new file mode 100644
index 0000000..6f186a1
--- /dev/null
+++ b/game/guitargraph.hh
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <boost/scoped_ptr.hpp>
+#include "animvalue.hh"
+#include "engine.hh"
+#include "surface.hh"
+
+class Song;
+
+/// handles drawing of notes and waves
+class GuitarGraph {
+ public:
+ /// constructor
+ GuitarGraph(Song const& song);
+
+ /** draws GuitarGraph
+ * @param time at which time to draw
+ */
+ void draw(double time);
+ private:
+ Song const& m_song;
+ Texture m_neck;
+};
+
diff --git a/game/notegraph.hh b/game/notegraph.hh
index 5144777..b9e166c 100644
--- a/game/notegraph.hh
+++ b/game/notegraph.hh
@@ -1,5 +1,4 @@
-#ifndef PERFORMOUS_NOTEGRAPH_HH
-#define PERFORMOUS_NOTEGRAPH_HH
+#pragma once
#include <boost/scoped_ptr.hpp>
#include "animvalue.hh"
@@ -42,5 +41,3 @@ class NoteGraph {
};
-#endif
-
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index a1c261e..919828a 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -37,11 +37,13 @@ void ScreenSing::enter() {
boost::ptr_vector<Analyzer>& analyzers = m_capture.analyzers();
m_engine.reset(new Engine(m_audio, m_songs.current(), analyzers.begin(), analyzers.end()));
m_noteGraph.reset(new NoteGraph(song));
+ if (song.music.size() > 1) m_guitarGraph.reset(new GuitarGraph(song));
}
void ScreenSing::exit() {
m_score_window.reset();
m_lyrics.clear();
+ m_guitarGraph.reset();
m_noteGraph.reset();
m_engine.reset();
m_pause_icon.reset();
@@ -116,7 +118,6 @@ namespace {
}
void ScreenSing::draw() {
- ScreenManager* sm = ScreenManager::getSingletonPtr();
Song& song = m_songs.current();
// Get the time in the song
double length = m_audio.getLength();
@@ -140,26 +141,8 @@ void ScreenSing::draw() {
theme->bg_top.draw();
}
- // Draw guitar stuff
- Texture tex(getThemePath("guitarneck.svg"));
- {
- UseTexture t(tex);
- glPushMatrix();
- glTranslatef(0.0f, 0.3f, 0.0f);
- glRotatef(80.0f, 1.0f, 0.0f, 0.0f);
- glScalef(0.1f, 0.1f, 0.1f);
- glBegin(GL_QUADS);
- float ts = 12.0f;
- float future = 3.0f;
- glTexCoord2f(0.0f, -(time + future)); glColor4f(1.0f, 1.0f, 1.0f, 0.0f); glVertex2f(-2.5f, -future * ts);
- glTexCoord2f(1.0f, -(time + future)); glColor4f(1.0f, 1.0f, 1.0f, 0.0f); glVertex2f(2.5f, -future * ts);
- glTexCoord2f(1.0f, -(time + 0.0f)); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glVertex2f(2.5f, 0.0f * ts);
- glTexCoord2f(0.0f, -(time + 0.0f)); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glVertex2f(-2.5f, 0.0f * ts);
- glEnd();
- glColor3f(1.0f, 1.0f, 1.0f);
- glPopMatrix();
- }
-
+ if (m_guitarGraph.get()) m_guitarGraph->draw(time);
+
if (!config["game/karaoke_mode"].b()) drawNonKaraoke(time);
// Compute and draw lyrics
@@ -201,6 +184,8 @@ void ScreenSing::draw() {
theme->timer.draw(statustxt);
}
+ ScreenManager* sm = ScreenManager::getSingletonPtr();
+
if (config["game/karaoke_mode"].b()) {
if (!m_audio.isPlaying()) sm->activateScreen("Songs");
} else {
diff --git a/game/screen_sing.hh b/game/screen_sing.hh
index 586908a..bcac4f0 100644
--- a/game/screen_sing.hh
+++ b/game/screen_sing.hh
@@ -1,11 +1,11 @@
-#ifndef PERFORMOUS_SCREEN_SING_HH
-#define PERFORMOUS_SCREEN_SING_HH
+#pragma once
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/scoped_ptr.hpp>
#include <deque>
#include "animvalue.hh"
#include "engine.hh"
+#include "guitargraph.hh"
#include "notegraph.hh"
#include "screen.hh"
#include "theme.hh"
@@ -96,6 +96,7 @@ class ScreenSing: public Screen {
boost::scoped_ptr<SvgTxtThemeSimple> m_score_text[2];
boost::scoped_ptr<Engine> m_engine;
boost::scoped_ptr<NoteGraph> m_noteGraph;
+ boost::scoped_ptr<GuitarGraph> m_guitarGraph;
double m_latencyAV; // Latency between audio and video output (do not confuse with latencyAR)
boost::scoped_ptr<ThemeSing> theme;
Notes::const_iterator m_lyricit;
@@ -103,4 +104,3 @@ class ScreenSing: public Screen {
AnimValue m_quitTimer;
};
-#endif
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-12 23:55:58
|
Module: performous
Branch: master
Commit: 6ebbf72a17a3391cef3bf889b6dad7dd1cce0dcf
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jul 13 02:40:34 2009 +0300
Play multiple tracks properly (somewhat).
---
game/screen_sing.cc | 4 ++--
game/screen_songs.cc | 2 +-
game/song.cc | 2 +-
game/song.hh | 2 +-
game/songparser-ini.cc | 5 ++++-
game/songparser-txt.cc | 2 +-
6 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index a58793f..a1c261e 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -15,8 +15,8 @@ namespace {
void ScreenSing::enter() {
Song& song = m_songs.current();
- std::string file = song.path + song.mp3;
- m_audio.playMusic(file.c_str());
+ std::cout << "DEBUG::::: " << song.music.size() << std::endl;
+ m_audio.playMusic(song.music);
theme.reset(new ThemeSing());
if (!song.background.empty()) {
try {
diff --git a/game/screen_songs.cc b/game/screen_songs.cc
index aac50e1..80e0aa7 100644
--- a/game/screen_songs.cc
+++ b/game/screen_songs.cc
@@ -142,7 +142,7 @@ void ScreenSongs::draw() {
s.tex = TexCoords(); glColor3f(1.0, 1.0, 1.0); // Restore default attributes
}
}
- if (!song.mp3.empty()) music = song.path + song.mp3;
+ if (!song.music.empty()) music = song.music[0]; // FIXME: support multiple tracks
if (!song.background.empty()) songbg = song.path + song.background;
if (!song.video.empty()) { video = song.path + song.video; videoGap = song.videoGap; }
}
diff --git a/game/song.cc b/game/song.cc
index 075f103..afdb8d5 100644
--- a/game/song.cc
+++ b/game/song.cc
@@ -14,7 +14,7 @@ void Song::reload(bool errorIgnore) {
collateByArtist.clear();
text.clear();
creator.clear();
- mp3.clear();
+ music.clear();
cover.clear();
background.clear();
video.clear();
diff --git a/game/song.hh b/game/song.hh
index 25acf17..6f7ec6c 100644
--- a/game/song.hh
+++ b/game/song.hh
@@ -48,7 +48,7 @@ class Song: boost::noncopyable {
std::string artist; ///< artist
std::string text; ///< songtext
std::string creator; ///< creator
- std::string mp3; ///< mp3
+ std::vector<std::string> music; ///< music files (background, guitar, rhythm/bass, drums, vocals)
std::string cover; ///< cd cover
std::string background; ///< background image
std::string video; ///< video
diff --git a/game/songparser-ini.cc b/game/songparser-ini.cc
index 6a00db6..87f8aa9 100644
--- a/game/songparser-ini.cc
+++ b/game/songparser-ini.cc
@@ -30,10 +30,13 @@ void SongParser::iniParse() {
else if (key == "artist") s.artist = value;
}
if (s.title.empty() || s.artist.empty()) throw std::runtime_error("Required header fields missing");
- s.mp3 = "song.ogg";
+ s.music.push_back(s.path + "song.ogg");
+ s.music.push_back(s.path + "guitar.ogg");
MidiFileParser midi(s.path + "/notes.mid");
for (MidiFileParser::TempoChanges::const_iterator it = midi.tempochanges.begin(); it != midi.tempochanges.end(); ++it) addBPM(it->miditime * 4, it->value);
for (MidiFileParser::Tracks::const_iterator it = midi.tracks.begin(); it != midi.tracks.end(); ++it) {
+ if (it->name == "PART RHYTHM" || it->name == "PART BASS") s.music.push_back(s.path + "rhythm.ogg");
+ if (it->name == "PART DRUMS") s.music.push_back(s.path + "drums.ogg");
if (it->name != "PART VOCALS") continue;
for (MidiFileParser::Lyrics::const_iterator it2 = it->lyrics.begin(); it2 != it->lyrics.end(); ++it2) {
Note n;
diff --git a/game/songparser-txt.cc b/game/songparser-txt.cc
index cc6aefb..0d89575 100644
--- a/game/songparser-txt.cc
+++ b/game/songparser-txt.cc
@@ -52,7 +52,7 @@ bool SongParser::txtParseField(std::string const& line) {
else if (key == "GENRE") m_song.genre = value.substr(value.find_first_not_of(" "));
else if (key == "CREATOR") m_song.creator = value.substr(value.find_first_not_of(" "));
else if (key == "COVER") m_song.cover = value;
- else if (key == "MP3") m_song.mp3 = value;
+ else if (key == "MP3") m_song.music.push_back(m_song.path + value);
else if (key == "VIDEO") m_song.video = value;
else if (key == "BACKGROUND") m_song.background = value;
else if (key == "START") assign(m_song.start, value);
|
|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-12 22:55:11
|
Module: performous Branch: master Commit: 6870311a6edaa2139ff61b520819212dcee08191 Author: Lasse Karkkainen <tro...@tr...> Date: Mon Jul 13 01:54:15 2009 +0300 Prototyping guitar rendering. --- game/screen_sing.cc | 20 ++++ game/video_driver.cc | 10 ++- themes/default/guitarneck.svg | 198 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 227 insertions(+), 1 deletions(-) |
|
From: Yoda-JM <yo...@us...> - 2009-07-12 14:41:14
|
Module: performous
Branch: master
Commit: db1865f9782f4792461f4d5279256b4cf684ab0a
Author: Vincent Le Ligeour <yo...@us...>
Date: Sun Jul 12 16:40:43 2009 +0200
Dirty fix of joystick problem
---
game/joystick.cc | 3 ++-
game/joystick.hh | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/game/joystick.cc b/game/joystick.cc
index fbd2a5f..a787e68 100644
--- a/game/joystick.cc
+++ b/game/joystick.cc
@@ -7,7 +7,8 @@ Joystick::Joystick(unsigned int _id): m_id(_id) {
m_joystick = SDL_JoystickOpen(m_id);
};
Joystick::~Joystick() {
- if(SDL_JoystickOpened(m_id)) SDL_JoystickClose(m_joystick);
+ // Do it another way :/
+ //if(SDL_JoystickOpened(m_id)) SDL_JoystickClose(m_joystick);
};
std::string Joystick::getName() const {
return std::string(SDL_JoystickName(m_id));
diff --git a/game/joystick.hh b/game/joystick.hh
index e6f4e6e..8ec4f61 100644
--- a/game/joystick.hh
+++ b/game/joystick.hh
@@ -14,7 +14,7 @@ void joysticks_init();
class Joystick {
public:
- Joystick() {};
+ Joystick() {};
Joystick(unsigned int _id);
~Joystick();
std::string getName() const;
|
|
From: Yoda-JM <yo...@us...> - 2009-07-12 11:25:51
|
Module: performous
Branch: master
Commit: afe071271c0c9802ae49bffc6d3ff8938b748a13
Author: Vincent Le Ligeour <yo...@us...>
Date: Sun Jul 12 13:24:19 2009 +0200
Added multiple audio track playback
---
game/audio.cc | 20 ++++++++++++++++++++
game/audio.hh | 1 +
2 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 09aa93f..3c79331 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -64,6 +64,26 @@ void Audio::operator()(da::pcm_data& areas, da::settings const&) {
}
}
+void Audio::playMusic(std::vector<std::string> const& filenames, bool preview, double fadeTime, double startPos) {
+ if (!isOpen()) return;
+ // First construct the new stream
+ fadeout(fadeTime);
+ for(unsigned int i = 0 ; i < filenames.size() ; i++ ) {
+ std::cout << "Adding " << filenames[i] << std::endl;
+ std::auto_ptr<Stream> s;
+ try {
+ s.reset(new Stream(filenames[i], m_rs.rate(), preview ? config["audio/preview_volume"] : config["audio/music_volume"]));
+ s->fadein(fadeTime);
+ if (startPos != 0.0) s->mpeg.seek(startPos, false);
+ } catch (std::runtime_error& e) {
+ std::cerr << "Error loading " << filenames[i] << " (" << e.what() << ")" << std::endl;
+ }
+ boost::recursive_mutex::scoped_lock l(m_mutex);
+ m_streams.push_back(s);
+ }
+ if (!preview) m_paused = false;
+}
+
void Audio::playMusic(std::string const& filename, bool preview, double fadeTime, double startPos) {
if (!isOpen()) return;
// First construct the new stream
diff --git a/game/audio.hh b/game/audio.hh
index d13784b..3378891 100644
--- a/game/audio.hh
+++ b/game/audio.hh
@@ -122,6 +122,7 @@ class Audio {
* @param startPos starting position
*/
void playMusic(std::string const& filename, bool preview = false, double fadeTime = 0.1, double startPos = 0.0);
+ void playMusic(std::vector<std::string> const& filenames, bool preview = false, double fadeTime = 0.1, double startPos = 0.0);
/** Play a preview of the song, starting at startPos
* @param filename the track filename
* @param startPos starting position
|