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:48:51
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Sat Mar 17 01:14:02 2012 +0200
Fix a compile error due to missing av_rescale_q by removing some unnecessary per-stream seeking logic.
---
game/ffmpeg.cc | 8 +-------
1 files changed, 1 insertions(+), 7 deletions(-)
diff --git a/game/ffmpeg.cc b/game/ffmpeg.cc
index 87efcfa..1f5d5b2 100644
--- a/game/ffmpeg.cc
+++ b/game/ffmpeg.cc
@@ -125,13 +125,7 @@ void FFmpeg::seek_internal() {
audioQueue.reset();
int flags = 0;
if (m_seekTarget < position()) flags |= AVSEEK_FLAG_BACKWARD;
- int stream = -1;
- if (decodeVideo) stream = videoStream;
- if (decodeAudio) stream = audioStream;
- int64_t target = m_seekTarget * AV_TIME_BASE;
- const AVRational time_base_q = { 1, AV_TIME_BASE }; // AV_TIME_BASE_Q is the same thing with C99 struct literal (not supported by MSVC)
- if (stream != -1) target = av_rescale_q(target, time_base_q, pFormatCtx->streams[stream]->time_base);
- av_seek_frame(pFormatCtx, stream, target, flags);
+ av_seek_frame(pFormatCtx, -1, m_seekTarget * AV_TIME_BASE, flags);
m_seekTarget = getNaN(); // Signal that seeking is done
}
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:48:49
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Feb 20 07:15:24 2012 +0200
Load a random background if background loading fails (screen_sing).
- Added empty() for Surface, allows testing if the loading has failed.
---
game/screen_sing.cc | 30 +++++-------------------------
game/surface.cc | 2 +-
game/surface.hh | 1 +
3 files changed, 7 insertions(+), 26 deletions(-)
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index 6b5ff3d..7b16fb4 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -135,26 +135,7 @@ void ScreenSing::reloadGL() {
m_help.reset(new Surface(getThemePath("instrumenthelp.svg")));
m_progress.reset(new ProgressBar(getThemePath("sing_progressbg.svg"), getThemePath("sing_progressfg.svg"), ProgressBar::HORIZONTAL, 0.01f, 0.01f, true));
// Load background
- bool foundbg = false;
- if (!m_song->background.empty()) { // Load bg image
- try {
- m_background.reset(new Surface(m_song->path + m_song->background));
- foundbg = true;
- } catch (std::exception& e) {
- m_song->background = "";
- std::cerr << e.what() << std::endl;
- }
- }
- // Use random bg if specified fails (also for tracks with video)
- if (!foundbg) {
- sm->loading(_("Random background..."), 0.65);
- try {
- std::string bgpath = m_backgrounds.getRandom();
- m_background.reset(new Surface(bgpath));
- } catch (std::exception& e) {
- std::cerr << e.what() << std::endl;
- }
- }
+ if (!m_song->background.empty()) m_background.reset(new Surface(m_song->path + m_song->background));
}
void ScreenSing::exit() {
@@ -444,11 +425,10 @@ void ScreenSing::draw() {
Transform ft(farTransform());
double ar = arMax;
// Background image
- if (m_background) {
- ar = m_background->dimensions.ar();
- if (ar > arMax || (m_video && ar > arMin)) fillBG(); // Fill white background to avoid black borders
- m_background->draw();
- } else fillBG(); // Blank
+ if (!m_background || m_background->empty()) m_background.reset(new Surface(m_backgrounds.getRandom()));
+ ar = m_background->dimensions.ar();
+ if (ar > arMax || (m_video && ar > arMin)) fillBG(); // Fill white background to avoid black borders
+ m_background->draw();
// Webcam
if (m_cam && config["graphic/webcam"].b()) m_cam->render();
// Video
diff --git a/game/surface.cc b/game/surface.cc
index a25e2f6..8f9bd1c 100644
--- a/game/surface.cc
+++ b/game/surface.cc
@@ -195,6 +195,6 @@ void Surface::load(Bitmap const& bitmap) {
}
void Surface::draw() const {
- if (m_width * m_height > 0.0) m_texture.draw(dimensions, TexCoords(tex.x1 * m_width, tex.y1 * m_height, tex.x2 * m_width, tex.y2 * m_height));
+ if (!empty()) m_texture.draw(dimensions, TexCoords(tex.x1 * m_width, tex.y1 * m_height, tex.x2 * m_width, tex.y2 * m_height));
}
diff --git a/game/surface.hh b/game/surface.hh
index 57a926e..055550f 100644
--- a/game/surface.hh
+++ b/game/surface.hh
@@ -221,6 +221,7 @@ class Surface {
/// creates surface from file
Surface(std::string const& filename);
~Surface();
+ bool empty() const { return m_width * m_height == 0; } ///< Test if the loading has failed
/// draws surface
void draw() const;
/// loads surface into buffer
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:48:46
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Feb 20 06:50:00 2012 +0200
Draw one more cover (outside the screen) on song browser to avoid seeing the loading of images when browsing.
---
game/screen_songs.cc | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/game/screen_songs.cc b/game/screen_songs.cc
index 64d621c..95a5d44 100644
--- a/game/screen_songs.cc
+++ b/game/screen_songs.cc
@@ -256,7 +256,7 @@ void ScreenSongs::drawCovers() {
std::size_t ss = m_songs.size();
int baseidx = spos + 1.5; --baseidx; // Round correctly
double shift = spos - baseidx;
- for (int i = -2; i < 5; ++i) {
+ for (int i = -2; i < 6; ++i) {
if (baseidx + i < 0 || baseidx + i >= int(ss)) continue;
Song& song = m_songs[baseidx + i];
Surface& s = getCover(song);
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:48:43
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Sun Feb 19 22:31:10 2012 +0200
Use black non-transparent placeholder texture instead of gray.
---
game/surface.cc | 3 ++-
game/surface.hh | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/game/surface.cc b/game/surface.cc
index fedf953..a25e2f6 100644
--- a/game/surface.cc
+++ b/game/surface.cc
@@ -115,8 +115,9 @@ struct Loader {
void updateSurfaces() { ldr.apply(); }
template <typename T> void loader(T* target, fs::path const& name) {
- // Temporarily add 1x1 pixel gray block
+ // Temporarily add 1x1 pixel black texture
Bitmap bitmap;
+ bitmap.fmt = pix::RGB;
bitmap.resize(1, 1);
target->load(bitmap);
// Ask the loader to retrieve the image
diff --git a/game/surface.hh b/game/surface.hh
index 1dc70fe..57a926e 100644
--- a/game/surface.hh
+++ b/game/surface.hh
@@ -171,7 +171,7 @@ struct Bitmap {
pix::Format fmt;
Bitmap(): width(), height(), ar(), fmt(pix::CHAR_RGBA) {}
void resize(unsigned w, unsigned h) {
- buf.resize(w * h * 4, 0x80);
+ buf.resize(w * h * 4);
width = w;
height = h;
ar = float(w) / h;
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:48:40
|
Author: Tapio Vierros <tap...@gm...>
Date: Sun Feb 19 22:10:34 2012 +0200
Fixed (hopefully all) aspect ratio issues with the new threaded gfx loading.
---
game/instrumentgraph.cc | 10 +++++-----
game/progressbar.cc | 2 ++
game/screen_intro.cc | 1 +
game/screen_practice.cc | 4 +++-
game/screen_sing.cc | 7 +++----
game/theme.cc | 10 ++--------
6 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/game/instrumentgraph.cc b/game/instrumentgraph.cc
index 6d25d3b..454196a 100644
--- a/game/instrumentgraph.cc
+++ b/game/instrumentgraph.cc
@@ -36,10 +36,6 @@ InstrumentGraph::InstrumentGraph(Audio& audio, Song const& song, input::DevType
m_popupText.reset(new SvgTxtThemeSimple(getThemePath("sing_popup_text.svg"), config["graphic/text_lod"].f()));
m_menuTheme.reset(new ThemeInstrumentMenu());
for (size_t i = 0; i < max_panels; ++i) m_pressed[i] = false;
- m_arrow_up.dimensions.stretch(0.05, 0.05);
- m_arrow_down.dimensions.stretch(0.05, 0.05);
- m_arrow_left.dimensions.stretch(0.05, 0.05);
- m_arrow_right.dimensions.stretch(0.05, 0.05);
}
@@ -73,8 +69,12 @@ void InstrumentGraph::drawMenu() {
Dimensions dimensions(1.0); // FIXME: bogus aspect ratio (is this fixable?)
if (getGraphType() == input::DANCEPAD) dimensions.screenTop().middle().stretch(m_width.get(), 1.0);
else dimensions.screenBottom().middle().fixedWidth(std::min(m_width.get(), 0.5));
- // Some helper vars
ThemeInstrumentMenu& th = *m_menuTheme;
+ th.back_h.dimensions.fixedHeight(0.08f);
+ m_arrow_up.dimensions.stretch(0.05, 0.05);
+ m_arrow_down.dimensions.stretch(0.05, 0.05);
+ m_arrow_left.dimensions.stretch(0.05, 0.05);
+ m_arrow_right.dimensions.stretch(0.05, 0.05);
MenuOptions::const_iterator cur = static_cast<MenuOptions::const_iterator>(&m_menu.current());
double w = m_menu.dimensions.w();
const float s = std::min(m_width.get(), 0.5) / w;
diff --git a/game/progressbar.cc b/game/progressbar.cc
index a2a8c78..2c0a12c 100644
--- a/game/progressbar.cc
+++ b/game/progressbar.cc
@@ -40,4 +40,6 @@ void ProgressBar::draw(float value) {
break;
default: throw std::logic_error("ProgressBar::draw(): unknown m_mode value");
}
+ // Reset dimensions due to async image loading
+ dimensions = Dimensions(m_bg.ar());
}
diff --git a/game/screen_intro.cc b/game/screen_intro.cc
index 6109b06..906df55 100644
--- a/game/screen_intro.cc
+++ b/game/screen_intro.cc
@@ -78,6 +78,7 @@ void ScreenIntro::draw_menu_options() {
const float sel_margin = 0.05;
const MenuOptions opts = m_menu.getOptions();
double submenuanim = 1.0 - std::min(1.0, std::abs(m_submenuAnim.get()-m_menu.getSubmenuLevel()));
+ theme->back_h.dimensions.fixedHeight(0.08f);
theme->back_h.dimensions.stretch(m_menu.dimensions.w(), theme->back_h.dimensions.h());
// Determine from which item to start
int start_i = std::min((int)m_menu.curIndex() - 1, (int)opts.size() - (int)showopts
diff --git a/game/screen_practice.cc b/game/screen_practice.cc
index 3f6862f..28f8197 100644
--- a/game/screen_practice.cc
+++ b/game/screen_practice.cc
@@ -16,7 +16,6 @@ void ScreenPractice::enter() {
// draw vu meters
for (unsigned int i = 0, mics = m_audio.analyzers().size(); i < mics; ++i) {
m_vumeters.push_back(new ProgressBar(getThemePath("vumeter_bg.svg"), getThemePath("vumeter_fg.svg"), ProgressBar::VERTICAL, 0.136, 0.023));
- m_vumeters.back().dimensions.screenBottom().left(-0.4 + i * 0.2).fixedWidth(0.04);
}
m_samples.push_back("drum bass");
m_samples.push_back("drum snare");
@@ -56,6 +55,8 @@ void ScreenPractice::draw() {
}
void ScreenPractice::draw_analyzers() {
+ theme->note.dimensions.fixedHeight(0.03f);
+ theme->sharp.dimensions.fixedHeight(0.09f);
MusicalScale scale;
boost::ptr_vector<Analyzer>& analyzers = m_audio.analyzers();
if (analyzers.empty()) return;
@@ -73,6 +74,7 @@ void ScreenPractice::draw_analyzers() {
}
// getPeak returns 0.0 when clipping, negative values when not that loud.
// Normalizing to [0,1], where 0 is -43 dB or less (to match the vumeter graphic)
+ m_vumeters[i].dimensions.screenBottom().left(-0.4 + i * 0.2).fixedWidth(0.04);
m_vumeters[i].draw(analyzer.getPeak() / 43.0 + 1.0);
if (freq != 0.0) {
diff --git a/game/screen_sing.cc b/game/screen_sing.cc
index dfb7a9e..6b5ff3d 100644
--- a/game/screen_sing.cc
+++ b/game/screen_sing.cc
@@ -134,8 +134,6 @@ void ScreenSing::reloadGL() {
m_pause_icon.reset(new Surface(getThemePath("sing_pause.svg")));
m_help.reset(new Surface(getThemePath("instrumenthelp.svg")));
m_progress.reset(new ProgressBar(getThemePath("sing_progressbg.svg"), getThemePath("sing_progressfg.svg"), ProgressBar::HORIZONTAL, 0.01f, 0.01f, true));
- m_progress->dimensions.fixedWidth(0.4).left(-0.5).screenTop();
- theme->timer.dimensions.screenTop(0.5 * m_progress->dimensions.h());
// Load background
bool foundbg = false;
if (!m_song->background.empty()) { // Load bg image
@@ -490,6 +488,8 @@ void ScreenSing::draw() {
// Compute and draw the timer and the progressbar
{
unsigned t = clamp(time, 0.0, length);
+ m_progress->dimensions.fixedWidth(0.4).left(-0.5).screenTop();
+ theme->timer.dimensions.screenTop(0.5 * m_progress->dimensions.h());
m_progress->draw(songPercent);
Song::SongSection section("error", 0);
@@ -661,7 +661,6 @@ ScoreWindow::ScoreWindow(Instruments& instruments, Database& database, Dancers&
}
}
m_bg.dimensions.middle().center();
- m_scoreBar.dimensions.fixedWidth(0.09);
}
void ScoreWindow::draw() {
@@ -675,7 +674,7 @@ void ScoreWindow::draw() {
int score = p->score;
ColorTrans c(p->color);
double x = -0.12 + spacing * (0.5 + i - 0.5 * m_database.scores.size());
- m_scoreBar.dimensions.middle(x).bottom(0.20);
+ m_scoreBar.dimensions.fixedWidth(0.09).middle(x).bottom(0.20);
m_scoreBar.draw(score / 10000.0);
m_score_text.render(boost::lexical_cast<std::string>(score));
m_score_text.dimensions().middle(x).top(0.24).fixedHeight(0.05);
diff --git a/game/theme.cc b/game/theme.cc
index dbaab57..ffcc88d 100644
--- a/game/theme.cc
+++ b/game/theme.cc
@@ -21,10 +21,7 @@ ThemePractice::ThemePractice():
note(getThemePath("practice_note.svg")),
sharp(getThemePath("practice_sharp.svg")),
note_txt(getThemePath("practice_txt.svg"), config["graphic/text_lod"].f())
-{
- note.dimensions.fixedHeight(0.03f);
- sharp.dimensions.fixedHeight(0.09f);
-}
+{}
ThemeSing::ThemeSing():
bg_top(getThemePath("sing_bg_top.svg")),
@@ -53,9 +50,7 @@ ThemeIntro::ThemeIntro():
short_comment(getThemePath("mainmenu_short_comment.svg"), config["graphic/text_lod"].f()),
comment_bg(getThemePath("mainmenu_comment_bg.svg")),
short_comment_bg(getThemePath("mainmenu_scomment_bg.svg"))
-{
- back_h.dimensions.fixedHeight(0.08f);
-}
+{}
ThemeInstrumentMenu::ThemeInstrumentMenu():
Theme(getThemePath("instrumentmenu_bg.svg")),
@@ -65,7 +60,6 @@ ThemeInstrumentMenu::ThemeInstrumentMenu():
comment(getThemePath("instrumentmenu_comment.svg"), config["graphic/text_lod"].f())
//comment_bg(getThemePath("menu_comment_bg.svg"))
{
- back_h.dimensions.fixedHeight(0.08f);
comment.setAlign(SvgTxtTheme::CENTER);
}
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:48:32
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Sun Feb 19 19:48:45 2012 +0200
Do not try to load background/video when they don't exist.
---
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 7dc98e8..64d621c 100644
--- a/game/screen_songs.cc
+++ b/game/screen_songs.cc
@@ -157,10 +157,10 @@ void ScreenSongs::update() {
double pstart = (!m_jukebox && song ? song->preview_start : 0.0);
m_audio.playMusic(music, true, 2.0, pstart);
if (song) {
- std::string background = song->path + song->background;
- std::string video = song->path + song->video;
- if (!background.empty()) try { m_songbg.reset(new Surface(background)); } catch (std::exception const&) {}
- if (!video.empty() && config["graphic/video"].b()) m_video.reset(new Video(video, song->videoGap));
+ std::string background = song->background;
+ std::string video = song->video;
+ if (!background.empty()) try { m_songbg.reset(new Surface(song->path + background)); } catch (std::exception const&) {}
+ if (!video.empty() && config["graphic/video"].b()) m_video.reset(new Video(song->path + video, song->videoGap));
}
}
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:48:26
|
Author: Lasse Karkkainen <tro...@tr...> Date: Sun Feb 19 19:40:26 2012 +0200 Implement threaded Surface/Texture loading. - Uses a background thread for image loading, renders grey squares until the loading is complete. - Removed support for hardware without NPOT. - Removed Cairo Surface constructor (no-one was using it). - Added extra pass in main loop for surface updates. - BUGS: various UI elements are incorrectly sized (too high). --- game/image.hh | 43 +++++++-------- game/main.cc | 3 + game/opengl_text.cc | 7 ++- game/surface.cc | 148 +++++++++++++++++++++++++++++++++++---------------- game/surface.hh | 39 +++++++++++-- game/video.cc | 7 ++- game/webcam.cc | 7 ++- 7 files changed, 173 insertions(+), 81 deletions(-) |
|
From: rainbyte <rai...@us...> - 2012-07-17 10:48:20
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Feb 13 07:19:32 2012 +0200
Attempt to improve glshader infolog printout.
- Ignore Radeon driver "all ok" messages (needs testing).
- Use the fine logging facility we have.
---
game/glshader.cc | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/game/glshader.cc b/game/glshader.cc
index 25beb98..f17803b 100644
--- a/game/glshader.cc
+++ b/game/glshader.cc
@@ -35,9 +35,9 @@ void Shader::dumpInfoLog(GLuint id) {
if (glIsShader(id)) glGetShaderInfoLog(id, maxLength, &infologLength, infoLog);
else glGetProgramInfoLog(id, maxLength, &infologLength, infoLog);
- if (infologLength > 0) {
- std::cout << std::endl << "Errors in shader '" << name << "':\n";
- std::cout << infoLog << std::endl;
+ if (infologLength > 0 && infoLog != "Vertex shader(s) linked, fragment shader(s) linked, geometry shader(s) linked." /* What the Radeon drivers always say */) {
+ // FIXME: The logging facility probably won't handle this right, especially when infoLog contains many lines.
+ std::clog << "opengl/error: Shader " << name << ": " << infoLog << std::endl;
}
}
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:48:15
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Feb 13 07:15:05 2012 +0200
Added FIXME.
---
game/guitargraph.cc | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index b068b27..4339b4a 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -1062,6 +1062,7 @@ void GuitarGraph::drawNote(int fret, Color color, float tBeg, float tEnd, float
vertexPair(va, x, y, color, doanim ? tc(y + t) : 1.0f); // First vertex pair
while ((y -= fretWid) > yEnd + fretWid) {
if (whammy > 0.1) {
+ // FIXME: Should use Boost/C++11 random, and use the same seed for both eyes in stereo3d.
float r1 = rand() / double(RAND_MAX) - 0.5;
float r2 = rand() / double(RAND_MAX) - 0.5;
vertexPair(va, x+0.2*(cos(y*whammy)+r1), y, color, tc(y + t), fretWid, 0.1*(sin(y*whammy)+r2));
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:48:08
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Feb 13 07:12:01 2012 +0200
Disable depth test for fret tail and alter rendering order to avoid rendering issues.
---
game/guitargraph.cc | 14 +++++++++-----
1 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index c4fca67..b068b27 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -1047,14 +1047,11 @@ void GuitarGraph::drawNote(int fret, Color color, float tBeg, float tEnd, float
if (releaseTime == releaseTime && tEnd - releaseTime > 0.1) yBeg = time2y(releaseTime);
// Short note? Render minimum renderable length
if (yEnd > yBeg - 3 * fretWid) yEnd = yBeg - 3 * fretWid;
- // Render the ring
+ // Skip the fret head
float y = yBeg + fretWid;
y -= fretWid;
+ float fretY = y;
color.a = clamp(time2a(tBeg)*2.0f,0.0f,1.0f);
- {
- ColorTrans c(color);
- m_fretObj.draw(x, y, 0.0f);
- }
y -= fretWid;
// Render the middle
bool doanim = hit || hitAnim > 0; // Enable glow?
@@ -1074,7 +1071,14 @@ void GuitarGraph::drawNote(int fret, Color color, float tBeg, float tEnd, float
y = yEnd + fretWid;
vertexPair(va, x, y, color, doanim ? tc(y + t) : 0.20f);
vertexPair(va, x, yEnd, color, doanim ? tc(yEnd + t) : 0.0f);
+ glDisable(GL_DEPTH_TEST);
va.Draw();
+ glEnable(GL_DEPTH_TEST);
+ // Render the fret object
+ {
+ ColorTrans c(color);
+ m_fretObj.draw(x, fretY, 0.0f);
+ }
} else {
// Too short note: only render the ring
if (hitAnim > 0.0 && tEnd <= maxTolerance) {
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:48:01
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Feb 13 06:55:53 2012 +0200
Remove 2d note support.
---
data/schema.xml | 4 ---
game/guitargraph.cc | 62 ++++++++++++++------------------------------------
game/guitargraph.hh | 1 -
3 files changed, 18 insertions(+), 49 deletions(-)
diff --git a/data/schema.xml b/data/schema.xml
index a51b769..75079da 100644
--- a/data/schema.xml
+++ b/data/schema.xml
@@ -173,10 +173,6 @@ to save the current settings to XML.
<short>Webcam id</short>
<long>Use -1 to autodetect or a number starting from 0 to choose specific device.</long>
</entry>
- <entry name="graphic/3d_notes" type="bool" value="true">
- <short>3D notes</short>
- <long>Draw instrument notes as 3-dimensional objects. May hurt performance on older hardware.</long>
- </entry>
<entry name="graphic/svg_lod" type="float" value="1.0">
<ui unit="x" />
<limits min="0.5" max="3.0" step="0.1" />
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index adf7338..c4fca67 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -104,7 +104,6 @@ GuitarGraph::GuitarGraph(Audio& audio, Song const& song, bool drums, int number)
m_neckglow(getThemePath("neck_glow.svg")),
m_neckglowColor(),
m_drums(drums),
- m_use3d(config["graphic/3d_notes"].b()),
m_level(),
m_track_index(m_instrumentTracks.end()),
m_dfIt(m_drumfills.end()),
@@ -1050,23 +1049,13 @@ void GuitarGraph::drawNote(int fret, Color color, float tBeg, float tEnd, float
if (yEnd > yBeg - 3 * fretWid) yEnd = yBeg - 3 * fretWid;
// Render the ring
float y = yBeg + fretWid;
- if (m_use3d) { // 3D
- y -= fretWid;
- color.a = clamp(time2a(tBeg)*2.0f,0.0f,1.0f);
- {
- ColorTrans c(color);
- m_fretObj.draw(x, y, 0.0f);
- }
- y -= fretWid;
- } else { // 2D
- color.a = time2a(tBeg);
- {
- ColorTrans c(color);
- m_button.dimensions.center(yBeg).middle(x);
- m_button.draw();
- }
- y -= 2 * fretWid;
+ y -= fretWid;
+ color.a = clamp(time2a(tBeg)*2.0f,0.0f,1.0f);
+ {
+ ColorTrans c(color);
+ m_fretObj.draw(x, y, 0.0f);
}
+ y -= fretWid;
// Render the middle
bool doanim = hit || hitAnim > 0; // Enable glow?
Texture const& tex(doanim ? m_tail_glow : m_tail); // Select texture
@@ -1088,42 +1077,27 @@ void GuitarGraph::drawNote(int fret, Color color, float tBeg, float tEnd, float
va.Draw();
} else {
// Too short note: only render the ring
- if (m_use3d) { // 3D
- if (hitAnim > 0.0 && tEnd <= maxTolerance) {
- float s = 1.0 - hitAnim;
- color.a = s;
- {
- ColorTrans c(color);
- m_fretObj.draw(x, yBeg, 0.0f, s);
- }
- } else {
- color.a = clamp(time2a(tBeg)*2.0f,0.0f,1.0f);
- {
- ColorTrans c(color);
- m_fretObj.draw(x, yBeg, 0.0f);
- }
+ if (hitAnim > 0.0 && tEnd <= maxTolerance) {
+ float s = 1.0 - hitAnim;
+ color.a = s;
+ {
+ ColorTrans c(color);
+ m_fretObj.draw(x, yBeg, 0.0f, s);
}
- } else { // 2D
- color.a = time2a(tBeg);
+ } else {
+ color.a = clamp(time2a(tBeg)*2.0f,0.0f,1.0f);
{
ColorTrans c(color);
- m_button.dimensions.center(yBeg).middle(x);
- m_button.draw();
+ m_fretObj.draw(x, yBeg, 0.0f);
}
}
}
// Hammer note caps
if (tappable) {
float l = std::max(0.3, m_correctness.get());
- if (m_use3d) { // 3D
- float s = 1.0 - hitAnim;
- ColorTrans c(Color(l, l, l, s));
- m_tappableObj.draw(x, yBeg, 0.0f, s);
- } else { // 2D
- ColorTrans c(Color(l, l, l));
- m_tap.dimensions.center(yBeg).middle(x);
- m_tap.draw();
- }
+ float s = 1.0 - hitAnim;
+ ColorTrans c(Color(l, l, l, s));
+ m_tappableObj.draw(x, yBeg, 0.0f, s);
}
}
diff --git a/game/guitargraph.hh b/game/guitargraph.hh
index dd97ffb..906df90 100644
--- a/game/guitargraph.hh
+++ b/game/guitargraph.hh
@@ -98,7 +98,6 @@ class GuitarGraph: public InstrumentGraph {
// Flags
bool m_drums; /// are we using drums?
- bool m_use3d; /// are we using 3d?
// Track stuff
enum Difficulty {
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:47:52
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Feb 13 06:21:56 2012 +0200
Experimenting with some 3d for guitar note bars and whammy effect. Needs testing + comments.
---
game/guitargraph.cc | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index 20883b3..adf7338 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -776,12 +776,12 @@ namespace {
const float fretWid = 0.5f; // The actual width is two times this
/// Create a symmetric vertex pair of given data
- void vertexPair(glutil::VertexArray& va, float x, float y, Color color, float ty, float fretW = fretWid) {
+ void vertexPair(glutil::VertexArray& va, float x, float y, Color color, float ty, float fretW = fretWid, float zn = 0.0) {
color.a = y2a(y);
{
glmath::vec4 c(color.r, color.g, color.b, color.a);
- va.Color(c).TexCoord(0.0f, ty).Vertex(x - fretW, y);
- va.Color(c).TexCoord(1.0f, ty).Vertex(x + fretW, y);
+ va.Color(c).TexCoord(0.0f, ty).Vertex(x - fretW, y, 0.1 + zn);
+ va.Color(c).TexCoord(1.0f, ty).Vertex(x + fretW, y, 0.1 - zn);
}
}
@@ -1076,8 +1076,9 @@ void GuitarGraph::drawNote(int fret, Color color, float tBeg, float tEnd, float
vertexPair(va, x, y, color, doanim ? tc(y + t) : 1.0f); // First vertex pair
while ((y -= fretWid) > yEnd + fretWid) {
if (whammy > 0.1) {
- float r = rand() / double(RAND_MAX);
- vertexPair(va, x+cos(y*whammy)/4.0+(r-0.5)/4.0, y, color, tc(y + t));
+ float r1 = rand() / double(RAND_MAX) - 0.5;
+ float r2 = rand() / double(RAND_MAX) - 0.5;
+ vertexPair(va, x+0.2*(cos(y*whammy)+r1), y, color, tc(y + t), fretWid, 0.1*(sin(y*whammy)+r2));
} else vertexPair(va, x, y, color, doanim ? tc(y + t) : 0.5f);
}
// Render the end
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:47:46
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Feb 13 05:44:08 2012 +0200
Comments for drawNotebar
---
game/notegraph.cc | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/game/notegraph.cc b/game/notegraph.cc
index e70fe5c..6340d6c 100644
--- a/game/notegraph.cc
+++ b/game/notegraph.cc
@@ -29,30 +29,31 @@ void NoteGraph::reset() {
namespace {
void drawNotebar(Texture const& texture, double x, double ybeg, double yend, double w, double h) {
glutil::VertexArray va;
-
UseTexture tblock(texture);
+ // The front cap begins
va.TexCoord(0.0f, 0.0f).Vertex(x, ybeg);
va.TexCoord(0.0f, 1.0f).Vertex(x, ybeg + h);
-
if (w >= 2.0 * h) {
- double tmp = h / w;
+ // Calculate the y coordinates of the middle part
+ double tmp = h / w; // h = cap size (because it is a h by h square)
double y1 = (1.0 - tmp) * ybeg + tmp * yend;
double y2 = tmp * ybeg + (1.0 - tmp) * yend;
-
+ // The middle part between caps
va.TexCoord(0.5f, 0.0f).Vertex(x + h, y1);
va.TexCoord(0.5f, 1.0f).Vertex(x + h, y1 + h);
va.TexCoord(0.5f, 0.0f).Vertex(x + w - h, y2);
va.TexCoord(0.5f, 1.0f).Vertex(x + w - h, y2 + h);
} else {
+ // Note is too short to even fit caps, crop to fit.
double ymid = 0.5 * (ybeg + yend);
float crop = 0.25f * w / h;
-
va.TexCoord(crop, 0.0f).Vertex(x + 0.5 * w, ymid);
va.TexCoord(crop, 1.0f).Vertex(x + 0.5 * w, ymid + h);
va.TexCoord(1.0f - crop, 0.0f).Vertex(x + 0.5 * w, ymid);
va.TexCoord(1.0f - crop, 1.0f).Vertex(x + 0.5 * w, ymid + h);
}
+ // The rear cap ends
va.TexCoord(1.0f, 0.0f).Vertex(x + w, yend);
va.TexCoord(1.0f, 1.0f).Vertex(x + w, yend + h);
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:47:39
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Feb 13 04:59:00 2012 +0200
Fix various AudioQueue bugs causing playback not to start or the previous song to keep playing. Prebuffering made faster.
- Race conditions due to improper locking when m_posReq was handled.
- Buffer fill level conditions may have behaved incorrectly in some cases, tests rewritten.
- Buffer size halved (allowed by bugfixes) and prebuffer reduced to 1/16th of capacity.
- Precise song duration set when decoding reaches EOF.
---
game/ffmpeg.cc | 1 +
game/ffmpeg.hh | 37 ++++++++++++++++++++++---------------
2 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/game/ffmpeg.cc b/game/ffmpeg.cc
index 4756997..87efcfa 100644
--- a/game/ffmpeg.cc
+++ b/game/ffmpeg.cc
@@ -110,6 +110,7 @@ void FFmpeg::operator()() {
}
m_running = false;
m_eof = true;
+ audioQueue.setEof();
videoQueue.push(new VideoFrame()); // EOF marker
}
diff --git a/game/ffmpeg.hh b/game/ffmpeg.hh
index 917b89b..6cbdd13 100644
--- a/game/ffmpeg.hh
+++ b/game/ffmpeg.hh
@@ -7,6 +7,7 @@
#include <boost/scoped_ptr.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/mutex.hpp>
+#include <boost/thread/recursive_mutex.hpp>
#include <boost/thread/thread.hpp>
#include <vector>
@@ -106,18 +107,19 @@ class VideoFifo {
};
class AudioBuffer {
+ typedef boost::recursive_mutex mutex;
public:
- AudioBuffer(size_t size = 2000000): m_data(size), m_pos(), m_posReq(), m_sps(), m_duration(getNaN()), m_quit() {}
+ AudioBuffer(size_t size = 1000000): m_data(size), m_pos(), m_posReq(), m_sps(), m_duration(getNaN()), m_quit() {}
/// Reset from FFMPEG side (seeking to beginning or terminate stream)
void reset() {
- boost::mutex::scoped_lock l(m_mutex);
+ mutex::scoped_lock l(m_mutex);
m_data.clear();
m_pos = 0;
l.unlock();
m_cond.notify_one();
}
void quit() {
- boost::mutex::scoped_lock l(m_mutex);
+ mutex::scoped_lock l(m_mutex);
m_quit = true;
l.unlock();
m_cond.notify_one();
@@ -127,7 +129,7 @@ class AudioBuffer {
/// get samples per second
unsigned getSamplesPerSecond() const { return m_sps; }
void push(std::vector<int16_t> const& data, double timestamp) {
- boost::mutex::scoped_lock l(m_mutex);
+ mutex::scoped_lock l(m_mutex);
while (!condition()) m_cond.wait(l);
if (m_quit) return;
if (m_pos == 0 && timestamp != 0.0) {
@@ -138,29 +140,28 @@ class AudioBuffer {
m_pos += data.size();
}
bool prepare(int64_t pos) {
- boost::mutex::scoped_try_lock l(m_mutex);
- if (!l.owns_lock()) return false;
+ mutex::scoped_try_lock l(m_mutex);
+ if (!l.owns_lock()) return false; // Didn't get lock, give up for now
if (eof(pos)) return true;
if (pos < 0) pos = 0;
m_posReq = pos;
+ wakeups();
// Has enough been prebuffered already and is the requested position still within buffer
- bool test = m_pos > m_posReq + m_data.capacity() / 16 && m_pos <= m_posReq + m_data.size();
- return test;
+ return m_pos > m_posReq + m_data.capacity() / 16 && m_pos <= m_posReq + m_data.size();
}
bool operator()(float* begin, float* end, int64_t pos, float volume = 1.0f) {
- boost::mutex::scoped_lock l(m_mutex);
+ mutex::scoped_lock l(m_mutex);
size_t idx = pos + m_data.size() - m_pos;
size_t samples = end - begin;
for (size_t s = 0; s < samples; ++s, ++idx) {
if (idx < m_data.size()) begin[s] += volume * da::conv_from_s16(m_data[idx]);
}
- m_posReq = pos + samples;
- l.unlock();
- if (wantSeek()) reset();
- if (condition()) m_cond.notify_one();
+ m_posReq = std::max<int64_t>(0, pos + samples);
+ wakeups();
return !eof(pos);
}
bool eof(int64_t pos) const { return double(pos) / m_sps >= m_duration; }
+ void setEof() { m_duration = double(m_pos) / m_sps; }
double duration() const { return m_duration; }
void setDuration(double seconds) { m_duration = seconds; }
bool wantSeek() {
@@ -168,9 +169,15 @@ class AudioBuffer {
return m_posReq > 0 && m_posReq + m_sps * 2 /* seconds tolerance */ + m_data.size() < m_pos;
}
private:
- bool wantMore() { return int64_t(m_pos) - int64_t(m_data.capacity() / 2) < m_posReq; }
+ /// Handle waking up of input thread etc. whenever m_posReq is changed.
+ void wakeups() {
+ if (wantSeek()) reset();
+ else if (condition()) m_cond.notify_one();
+ }
+ bool wantMore() { return m_pos < m_posReq + m_data.capacity() / 2; }
+ /// Should the input stop waiting?
bool condition() { return m_quit || wantMore() || wantSeek(); }
- mutable boost::mutex m_mutex;
+ mutable mutex m_mutex;
boost::condition m_cond;
boost::circular_buffer<int16_t> m_data;
size_t m_pos;
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:47:31
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Feb 13 03:22:31 2012 +0200
Fix note positioning in practice screen.
---
game/screen_practice.cc | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/game/screen_practice.cc b/game/screen_practice.cc
index 27bcc21..3f6862f 100644
--- a/game/screen_practice.cc
+++ b/game/screen_practice.cc
@@ -85,7 +85,7 @@ void ScreenPractice::draw_analyzers() {
int octave = note / 12 - 1;
double noteOffset = scale.getNoteNum(note);
bool sharp = scale.isSharp(note);
- noteOffset += octave*7;
+ noteOffset += (octave - 3) * 7;
noteOffset += 0.4 * scale.getNoteOffset(t->freq);
float posXnote = -0.25 + 0.2 * i + 0.002 * t->stabledb;
float posYnote = .075-noteOffset*0.015;
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:47:23
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Feb 13 03:18:27 2012 +0200
Yet another FFMPEG API switch (remove deprecated function calls). Use proper scope for AVFrameWrapper.
---
game/ffmpeg.cc | 26 +++++++++++++-------------
1 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/game/ffmpeg.cc b/game/ffmpeg.cc
index bc84f8c..4756997 100644
--- a/game/ffmpeg.cc
+++ b/game/ffmpeg.cc
@@ -45,7 +45,7 @@ void FFmpeg::open() {
boost::mutex::scoped_lock l(s_avcodec_mutex);
av_register_all();
av_log_set_level(AV_LOG_ERROR);
- if (av_open_input_file(&pFormatCtx, m_filename.c_str(), NULL, 0, NULL)) throw std::runtime_error("Cannot open input file");
+ if (avformat_open_input(&pFormatCtx, m_filename.c_str(), NULL, NULL)) throw std::runtime_error("Cannot open input file");
if (av_find_stream_info(pFormatCtx) < 0) throw std::runtime_error("Cannot find stream information");
pFormatCtx->flags |= AVFMT_FLAG_GENPTS;
videoStream = -1;
@@ -63,14 +63,14 @@ void FFmpeg::open() {
AVCodecContext* cc = pFormatCtx->streams[videoStream]->codec;
pVideoCodec = avcodec_find_decoder(cc->codec_id);
if (!pVideoCodec) throw std::runtime_error("Cannot find video codec");
- if (avcodec_open(cc, pVideoCodec) < 0) throw std::runtime_error("Cannot open video codec");
+ if (avcodec_open2(cc, pVideoCodec, NULL) < 0) throw std::runtime_error("Cannot open video codec");
pVideoCodecCtx = cc;
}
if (decodeAudio) {
AVCodecContext* cc = pFormatCtx->streams[audioStream]->codec;
pAudioCodec = avcodec_find_decoder(cc->codec_id);
if (!pAudioCodec) throw std::runtime_error("Cannot find audio codec");
- if (avcodec_open(cc, pAudioCodec) < 0) throw std::runtime_error("Cannot open audio codec");
+ if (avcodec_open2(cc, pAudioCodec, NULL) < 0) throw std::runtime_error("Cannot open audio codec");
pAudioCodecCtx = cc;
pResampleCtx = av_audio_resample_init(AUDIO_CHANNELS, cc->channels, m_rate, cc->sample_rate, SAMPLE_FMT_S16, SAMPLE_FMT_S16, 16, 10, 0, 0.8);
if (!pResampleCtx) throw std::runtime_error("Cannot create resampling context");
@@ -146,16 +146,6 @@ struct ReadFramePacket: public AVPacket {
}
};
-struct AVFrameWrapper {
- AVFrame* m_frame;
- AVFrameWrapper(): m_frame(avcodec_alloc_frame()) {
- if (!m_frame) throw std::runtime_error("Unable to allocate AVFrame");
- }
- ~AVFrameWrapper() { av_free(m_frame); }
- operator AVFrame*() { return m_frame; }
- AVFrame* operator->() { return m_frame; }
-} videoFrame;
-
void FFmpeg::decodePacket() {
ReadFramePacket packet(pFormatCtx);
int packetSize = packet.size;
@@ -171,6 +161,16 @@ void FFmpeg::decodePacket() {
}
int FFmpeg::decodeVideoFrame(ReadFramePacket& packet) {
+ struct AVFrameWrapper {
+ AVFrame* m_frame;
+ AVFrameWrapper(): m_frame(avcodec_alloc_frame()) {
+ if (!m_frame) throw std::runtime_error("Unable to allocate AVFrame");
+ }
+ ~AVFrameWrapper() { av_free(m_frame); }
+ operator AVFrame*() { return m_frame; }
+ AVFrame* operator->() { return m_frame; }
+ } videoFrame;
+
int frameFinished = 0;
int decodeSize = avcodec_decode_video2(pVideoCodecCtx, videoFrame, &frameFinished, &packet);
if (decodeSize < 0) throw std::runtime_error("cannot decode video frame");
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:47:15
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Feb 13 03:16:20 2012 +0200
Refresh the song list only twice a second while loading to reduce CPU load and to make the loading faster. Lower-case log categories.
---
game/songs.cc | 14 ++++++++------
game/songs.hh | 1 +
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/game/songs.cc b/game/songs.cc
index f132523..d0ec553 100644
--- a/game/songs.cc
+++ b/game/songs.cc
@@ -18,6 +18,7 @@
#include <cstdlib>
Songs::Songs(Database & database, std::string const& songlist): m_songlist(songlist), math_cover(), m_typeFilter(), m_database(database), m_order(), m_dirty(false), m_loading(false) {
+ m_updateTimer.setTarget(getInf()); // Using this as a simple timer counting seconds
reload();
}
@@ -44,13 +45,13 @@ void Songs::reload_internal() {
for (Paths::iterator it = paths.begin(); m_loading && it != paths.end(); ++it) {
try {
if (!fs::is_directory(*it)) { m_debug << "Songs/info: >>> Not scanning: " << *it << " (no such directory)" << std::endl; continue; }
- m_debug << "Songs/info: >>> Scanning " << *it << std::endl;
+ m_debug << "songs/info: >>> Scanning " << *it << std::endl;
size_t count = m_songs.size();
reload_internal(*it);
size_t diff = m_songs.size() - count;
if (diff > 0 && m_loading) m_debug << diff << " songs loaded" << std::endl;
} catch (std::exception& e) {
- m_debug << "Songs/error: >>> Error scanning " << *it << ": " << e.what() << std::endl;
+ m_debug << "songs/error: >>> Error scanning " << *it << ": " << e.what() << std::endl;
}
}
prof("total");
@@ -60,7 +61,7 @@ void Songs::reload_internal() {
void Songs::reload_internal(fs::path const& parent) {
namespace fs = fs;
- if (std::distance(parent.begin(), parent.end()) > 20) { m_debug << "Songs/info: >>> Not scanning: " << parent.string() << " (maximum depth reached, possibly due to cyclic symlinks)" << std::endl; return; }
+ if (std::distance(parent.begin(), parent.end()) > 20) { m_debug << "songs/info: >>> Not scanning: " << parent.string() << " (maximum depth reached, possibly due to cyclic symlinks)" << std::endl; return; }
try {
boost::regex expression("(.*\\.txt|^song\\.ini|notes\\.xml|.*\\.sm)$", boost::regex_constants::icase);
boost::cmatch match;
@@ -85,13 +86,13 @@ void Songs::reload_internal(fs::path const& parent) {
} catch (SongParserException& e) {
if (e.silent()) continue;
// Construct error message
- m_debug << "Songs/error: -!- Error in " << path << "\n " << name;
+ m_debug << "songs/error: -!- Error in " << path << "\n " << name;
if (e.line()) m_debug << " line " << e.line();
m_debug << ": " << e.what() << std::endl;
}
}
} catch (std::exception const& e) {
- m_debug << "Songs/error: Error accessing " << parent << e.what() << std::endl;
+ m_debug << "songs/error: Error accessing " << parent << e.what() << std::endl;
}
}
@@ -120,7 +121,7 @@ class Songs::RestoreSel {
};
void Songs::update() {
- if (m_dirty) filter_internal(); // Update with newly loaded songs
+ if (m_dirty && m_updateTimer.get() > 0.5) filter_internal(); // Update with newly loaded songs
// A hack to move to the first song when the song screen is entered the first time
static bool first = true;
if (first) { first = false; math_cover.setTarget(0, 0); math_cover.setTarget(0, size()); }
@@ -139,6 +140,7 @@ void Songs::setTypeFilter(unsigned char filter) {
}
void Songs::filter_internal() {
+ m_updateTimer.setValue(0.0);
boost::mutex::scoped_lock l(m_mutex);
// Print messages when loading has finished
if (!m_loading) {
diff --git a/game/songs.hh b/game/songs.hh
index 70b5a2a..45a0bd7 100644
--- a/game/songs.hh
+++ b/game/songs.hh
@@ -69,6 +69,7 @@ class Songs: boost::noncopyable {
typedef std::vector<boost::shared_ptr<Song> > SongVector;
std::string m_songlist;
SongVector m_songs, m_filtered;
+ AnimValue m_updateTimer;
AnimAcceleration math_cover;
std::string m_filter;
unsigned char m_typeFilter;
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:47:08
|
Author: Lasse Karkkainen <tro...@tr...> Date: Mon Feb 13 01:13:29 2012 +0200 Fix the class name in a warning message. --- game/surface.cc | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/game/surface.cc b/game/surface.cc index 5b7078b..a09763a 100644 --- a/game/surface.cc +++ b/game/surface.cc @@ -114,7 +114,7 @@ void Texture::load(unsigned int width, unsigned int height, pix::Format format, // Every developer of the game so far has tried doing so, but it just cannot work. // (1) no repeat => cannot texture // (2) coordinates not normalized => would require special hackery elsewhere - // Just don't do it in Surface class, thanks. -Tronic + // Just don't do it in Texture class, thanks. -Tronic glTexImage2D(type(), 0, internalFormat(), newWidth, newHeight, 0, f.format, f.type, &outBuf[0]); } glGenerateMipmap(type()); |
|
From: rainbyte <rai...@us...> - 2012-07-17 10:47:00
|
Author: Lasse Karkkainen <tro...@tr...> Date: Sun Feb 12 09:24:52 2012 +0200 FFMPEG cleanup. Buffering bugfixes and some rewriting/restructuring of code. --- game/ffmpeg.cc | 234 +++++++++++++++++++------------------------------------- game/ffmpeg.hh | 25 +++--- 2 files changed, 93 insertions(+), 166 deletions(-) |
|
From: rainbyte <rai...@us...> - 2012-07-17 10:46:53
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Sun Feb 12 05:22:28 2012 +0200
Fix regression: vocal note power glow.
Make the glow fade away smoothly.
---
game/engine.hh | 2 --
game/notes.cc | 9 ++++++---
game/notes.hh | 10 ++++++----
game/player.cc | 6 +++++-
4 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/game/engine.hh b/game/engine.hh
index 5fcb10b..7ea1cea 100644
--- a/game/engine.hh
+++ b/game/engine.hh
@@ -59,8 +59,6 @@ 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; }
- // 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/notes.cc b/game/notes.cc
index 258fec2..0e365f7 100644
--- a/game/notes.cc
+++ b/game/notes.cc
@@ -10,10 +10,13 @@ Note::Note(): begin(getNaN()), end(getNaN()), phase(getNaN()), power(getNaN()),
double Note::diff(double note, double n) { return remainder(n - note, 12.0); }
double Note::maxScore() const { return scoreMultiplier() * (end - begin); }
-double Note::score(double n, double b, double e) const {
+double Note::clampDuration(double b, double e) const {
double len = std::min(e, end) - std::max(b, begin);
- if (len <= 0.0 || !(n > 0.0)) return 0.0;
- return scoreMultiplier() * powerFactor(n) * len;
+ return len > 0.0 ? len : 0.0;
+}
+
+double Note::score(double n, double b, double e) const {
+ return scoreMultiplier() * powerFactor(n) * clampDuration(b, e);
}
double Note::scoreMultiplier() const {
diff --git a/game/notes.hh b/game/notes.hh
index ebc5daf..444c68f 100644
--- a/game/notes.hh
+++ b/game/notes.hh
@@ -71,15 +71,17 @@ struct Note {
double diff(double n) const { return diff(note, n); }
/// Difference of n from note, so that note + diff(note, n) is n (mod 12)
static double diff(double note, double n);
- /// maximum score
+ /// Maximum score
double maxScore() const;
- /// score when singing over time period (a, b), which needs not to be entirely within the note
+ /// The length of the time period [a,b] that falls within the note in seconds
+ double clampDuration(double b, double e) const;
+ /// Score when singing over time period (a, b), which needs not to be entirely within the note
double score(double freq, double b, double e) const;
/// How precisely the note is hit (always 1.0 for freestyle, 0..1 for others)
double powerFactor(double note) const;
- /// compares begin of two notes
+ /// Compares begin of two notes
static bool ltBegin(Note const& a, Note const& b) { return a.begin < b.begin; }
- /// compares end of two notes
+ /// Compares end of two notes
static bool ltEnd(Note const& a, Note const& b) { return a.end < b.end; }
private:
double scoreMultiplier() const;
diff --git a/game/player.cc b/game/player.cc
index 01f5254..d92a989 100644
--- a/game/player.cc
+++ b/game/player.cc
@@ -9,6 +9,8 @@ Player::Player(VocalTrack& vocal, Analyzer& analyzer, size_t frames):
m_prevLineScore(-1), m_feedbackFader(0.0, 2.0), m_activitytimer(),
m_scoreIt(m_vocal.notes.begin())
{
+ // Initialize note powers
+ for (Notes::const_iterator it = m_vocal.notes.begin(); it != m_vocal.notes.end(); ++it) it->power = 0.0f;
// Assign colors
if (m_analyzer.getId() == "blue") m_color = Color(0.2, 0.5, 0.7);
else if (m_analyzer.getId() == "red") m_color = Color(0.8, 0.3, 0.3);
@@ -34,6 +36,7 @@ void Player::update() {
while (m_scoreIt != m_vocal.notes.end()) {
if (endTime < m_scoreIt->begin) break; // The note begins later than on this timestep
// If tone was detected, calculate score
+ m_scoreIt->power *= std::pow(0.05, m_scoreIt->clampDuration(beginTime, endTime)); // Fade glow
if (t) {
double note = m_vocal.scale.getNote(t->freq);
// Add score
@@ -57,6 +60,7 @@ void Player::update() {
m_scoreIt->stars.push_back(m_color);
}
m_noteScore = 0; // Reset noteScore as we are moving on to the next one
+ m_scoreIt->power = 0.0; // Remove glow
++m_scoreIt;
}
if (m_scoreIt == m_vocal.notes.end()) calcRowRank();
@@ -68,7 +72,7 @@ void Player::calcRowRank() {
m_prevLineScore = m_lineScore;
// Calculate max score of the completed row
Notes::const_reverse_iterator maxScoreIt(m_scoreIt);
- // FIXME: MacOSX needs the following cast to compile correctly
+ // NOTE: MacOSX needs the following cast to compile correctly
// it is related to the fact that OSX default compiler is 4.0.1 that is buggy when not casting
while ((maxScoreIt != static_cast<Notes::const_reverse_iterator>(m_vocal.notes.rend())) && (maxScoreIt->type != Note::SLEEP)) {
m_maxLineScore += m_vocal.m_scoreFactor * maxScoreIt->maxScore();
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:46:46
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Sun Feb 12 04:16:36 2012 +0200
Use fatal error handling for fatal errors rather than flash messages.
---
game/main.cc | 11 ++---------
1 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/game/main.cc b/game/main.cc
index db3adde..997e5d3 100644
--- a/game/main.cc
+++ b/game/main.cc
@@ -207,15 +207,8 @@ void mainLoop(std::string const& songlist) {
}
}
} catch (std::exception& e) {
- // This should use ScreenManager fatalError, but it cannot
- // yet split the message to multiple lines automatically, so
- // better use flashMessage, which zooms to fit.
- std::cerr << "FATAL ERROR: " << e.what() << std::endl;
- sm.flashMessage(std::string("FATAL ERROR: ") + e.what(), 0.0f); // No fade-in to get it to show
- window.blank();
- sm.drawNotifications();
- window.swap();
- boost::thread::sleep(now() + 2.0);
+ sm.fatalError(e.what()); // Notify the user
+ throw;
} catch (QuitNow&) {
std::cout << "Terminated." << std::endl;
}
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:46:44
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Sun Feb 12 04:16:06 2012 +0200
Fix fatal error message display (was small and upside-down). Still no word-wrapping or scaling to fit.
---
game/screenmanager.cc | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/game/screenmanager.cc b/game/screenmanager.cc
index 5b289b8..f3b30f7 100644
--- a/game/screenmanager.cc
+++ b/game/screenmanager.cc
@@ -73,13 +73,11 @@ void ScreenManager::drawLoading() {
}
void ScreenManager::fatalError(std::string const& message) {
- std::cerr << "FATAL ERROR: " << message << std::endl;
- dialog(message);
+ dialog("FATAL ERROR\n\n" + message);
m_window.blank();
- drawNotifications();
+ m_window.render(boost::bind(&ScreenManager::drawNotifications, this));
m_window.swap();
boost::thread::sleep(now() + 4.0);
- std::exit(EXIT_FAILURE);
}
void ScreenManager::flashMessage(std::string const& message, float fadeIn, float hold, float fadeOut) {
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:46:36
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Sun Feb 12 04:00:42 2012 +0200
Fix bad_alloc crash on some songs (due to vocal track endTime being NaN). Needs testing.
---
game/engine.hh | 11 +++++------
1 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/game/engine.hh b/game/engine.hh
index 7ebeeb6..5fcb10b 100644
--- a/game/engine.hh
+++ b/game/engine.hh
@@ -31,12 +31,11 @@ class Engine {
template <typename FwdIt> Engine(Audio& audio, VocalTrackPtrs vocals, FwdIt anBegin, FwdIt anEnd, Database& database):
m_audio(audio), m_time(), m_quit(), m_database(database)
{
- 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;
+ if (vocals.empty()) throw std::runtime_error("Engine needs at least one vocal track");
+ // Remove unsensibly long tracks (also NaN)
+ for (VocalTrackPtrs::iterator it = vocals.begin(); it != vocals.end(); ) {
+ if ((*it) && (*it)->endTime < 10000.0) ++it; else it = vocals.erase(it);
+ }
// Clear old player information
m_database.cur.clear();
m_database.scores.clear();
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:46:30
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Sat Feb 11 08:51:26 2012 +0200
Make Songs::currentPtr return NULL instead of segfaulting if there are no songs.
---
game/songs.hh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/game/songs.hh b/game/songs.hh
index d403139..70b5a2a 100644
--- a/game/songs.hh
+++ b/game/songs.hh
@@ -46,7 +46,7 @@ class Songs: boost::noncopyable {
/// sets margins for animation
void setAnimMargins(double left, double right) { math_cover.setMargins(left, right); }
/// @return current song
- boost::shared_ptr<Song> currentPtr() { return m_filtered[math_cover.getTarget()]; }
+ boost::shared_ptr<Song> currentPtr() { return m_filtered.empty() ? boost::shared_ptr<Song>() : m_filtered[math_cover.getTarget()]; }
/// @return current song
Song& current() { return *m_filtered[math_cover.getTarget()]; }
/// @return current Song
|
|
From: rainbyte <rai...@us...> - 2012-07-17 10:46:22
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Sat Feb 11 08:37:27 2012 +0200
Major cleanup of screen songs with some bugfixes.
- Update logic separated from drawing functions
- Browser would hang due to auto-advance when all the songs displayed had the same music files
- Only update songlist when idle (allows for smooth browsing during song loading)
- Various other small things and almost certainly new bugs...
---
game/screen_songs.cc | 76 +++++++++++++++++++++++++------------------------
game/screen_songs.hh | 16 ++--------
game/song.hh | 3 +-
3 files changed, 44 insertions(+), 51 deletions(-)
diff --git a/game/screen_songs.cc b/game/screen_songs.cc
index bf8fa63..7dc98e8 100644
--- a/game/screen_songs.cc
+++ b/game/screen_songs.cc
@@ -17,7 +17,7 @@ ScreenSongs::ScreenSongs(std::string const& name, Audio& audio, Songs& songs, Da
Screen(name), m_audio(audio), m_songs(songs), m_database(database), m_covers(20), m_jukebox(), show_hiscores(), hiscore_start_pos()
{
m_songs.setAnimMargins(5.0, 5.0);
- m_playTimer.setTarget(getInf()); // Using this as a simple timer counting seconds
+ m_idleTimer.setTarget(getInf()); // Using this as a simple timer counting seconds
}
void ScreenSongs::enter() {
@@ -53,7 +53,6 @@ void ScreenSongs::exit() {
m_songbg_default.reset();
m_songbg_ground.reset();
m_playing.clear();
- m_playReq.clear();
}
/**Add actions here which should effect both the
@@ -77,6 +76,7 @@ void ScreenSongs::manageEvent(SDL_Event event) {
input::NavButton nav(input::getNav(event));
// Handle basic navigational input that is possible also with instruments
if (nav != input::NONE) {
+ m_idleTimer.setValue(0.0); // Reset idle timer
if (m_jukebox) {
if (nav == input::CANCEL || m_songs.empty()) m_jukebox = false;
else if (nav == input::UP) m_audio.seek(5);
@@ -128,6 +128,42 @@ void ScreenSongs::manageEvent(SDL_Event event) {
sm->showLogo(!m_jukebox);
}
+void ScreenSongs::update() {
+ if (m_idleTimer.get() < 0.3) return; // Only update when the user gives us a break
+ m_songs.update(); // Poll for new songs
+ bool songChange = false; // Do we need to switch songs?
+ // Automatic song browsing
+ if (!m_audio.isPaused() && m_idleTimer.get() > 1.0) {
+ // If playback has ended or hasn't started
+ if (!m_audio.isPlaying() || m_audio.getPosition() > m_audio.getLength()) {
+ songChange = true; // Force reload even if the music happens to stay the same
+ }
+ // If the above, or if in regular mode and idle too long, advance to next song
+ if (songChange || (!m_jukebox && m_idleTimer.get() > IDLE_TIMEOUT)) {
+ m_songs.advance(1);
+ m_idleTimer.setValue(0.0);
+ }
+ }
+ // Check out if the music has changed
+ boost::shared_ptr<Song> song = m_songs.currentPtr();
+ Song::Music music;
+ if (song) music = song->music;
+ if (m_playing != music) songChange = true;
+ // Switch songs if needed, only when the user is not browsing for a moment
+ if (!songChange) return;
+ m_playing = music;
+ // Clear the old content and load new content if available
+ m_songbg.reset(); m_video.reset();
+ double pstart = (!m_jukebox && song ? song->preview_start : 0.0);
+ m_audio.playMusic(music, true, 2.0, pstart);
+ if (song) {
+ std::string background = song->path + song->background;
+ std::string video = song->path + song->video;
+ if (!background.empty()) try { m_songbg.reset(new Surface(background)); } catch (std::exception const&) {}
+ if (!video.empty() && config["graphic/video"].b()) m_video.reset(new Video(video, song->videoGap));
+ }
+}
+
void ScreenSongs::drawJukebox() {
double pos = m_audio.getPosition();
double len = m_audio.getLength();
@@ -166,27 +202,6 @@ void ScreenSongs::drawMultimedia() {
}
}
-void ScreenSongs::updateMultimedia(Song& song, ScreenSharedInfo& info) {
- if (!song.music.empty()) info.music = song.music; // TODO it is always empty?
- if (!song.background.empty()) info.songbg = song.path + song.background;
- if (!song.video.empty()) { info.video = song.path + song.video; info.videoGap = song.videoGap; }
-}
-
-void ScreenSongs::stopMultimedia(ScreenSharedInfo& info) {
- // Schedule playback change if the chosen song has changed
- if (info.music != m_playReq) { m_playReq = info.music; m_playTimer.setValue(0.0); }
- // 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.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));
- m_playing = info.music;
- }
-}
-
namespace {
float getIconTex(int i) {
static int iconcount = 8;
@@ -195,10 +210,7 @@ namespace {
}
void ScreenSongs::draw() {
- m_songs.update(); // Poll for new songs
- ScreenSharedInfo info;
- info.videoGap = 0.0;
-
+ update();
drawMultimedia();
std::ostringstream oss_song, oss_order, oss_has_hiscore;
// Test if there are no songs
@@ -226,7 +238,6 @@ void ScreenSongs::draw() {
// Get hiscores from database
m_database.queryPerSongHiscore_HiscoreDisplay(oss_order, m_songs.currentPtr(), hiscore_start_pos, 5);
}
- updateMultimedia(song, info);
}
if (m_jukebox) drawJukebox();
else {
@@ -238,15 +249,6 @@ void ScreenSongs::draw() {
} else theme->hiscores.draw(oss_order.str());
if (!show_hiscores) drawInstruments(Dimensions(m_instrumentList->ar()).fixedHeight(0.03).center(-0.04));
}
- stopMultimedia(info);
- if (m_jukebox) {
- // Switch if at song end
- if (!m_audio.isPlaying() || m_audio.getPosition() + 1.3 > m_audio.getLength()) {
- m_songs.advance(1);
- // Force reload of data
- m_playing.clear();
- }
- } else if (!m_audio.isPaused() && m_playTimer.get() > IDLE_TIMEOUT) m_songs.advance(1); // Switch if song hasn't changed for IDLE_TIMEOUT seconds
}
void ScreenSongs::drawCovers() {
diff --git a/game/screen_songs.hh b/game/screen_songs.hh
index 4fd16ff..a04d18e 100644
--- a/game/screen_songs.hh
+++ b/game/screen_songs.hh
@@ -15,14 +15,6 @@ class Song;
class Audio;
class Songs;
-struct ScreenSharedInfo
-{
- std::map<std::string,std::string> music;
- std::string songbg;
- std::string video;
- double videoGap;
-};
-
/// song chooser screen
class ScreenSongs : public Screen {
public:
@@ -41,8 +33,7 @@ public:
protected:
void drawInstruments(Dimensions const& dim, float alpha = 1.0f) const;
void drawMultimedia();
- void updateMultimedia(Song& song, ScreenSharedInfo& info);
- void stopMultimedia(ScreenSharedInfo& info);
+ void update();
Audio& m_audio;
Songs& m_songs;
@@ -50,9 +41,8 @@ protected:
boost::scoped_ptr<Surface> m_songbg, m_songbg_ground, m_songbg_default;
boost::scoped_ptr<Video> m_video;
boost::scoped_ptr<ThemeSongs> theme;
- std::map<std::string,std::string> m_playing;
- std::map<std::string,std::string> m_playReq;
- AnimValue m_playTimer;
+ Song::Music m_playing;
+ AnimValue m_idleTimer;
TextInput m_search;
boost::scoped_ptr<Surface> m_singCover;
boost::scoped_ptr<Surface> m_instrumentCover;
diff --git a/game/song.hh b/game/song.hh
index 726c0ca..a2b1b73 100644
--- a/game/song.hh
+++ b/game/song.hh
@@ -104,7 +104,8 @@ class Song: boost::noncopyable {
std::string text; ///< songtext
std::string creator; ///< creator
std::string language; ///< language
- std::map<std::string,std::string> music; ///< music files (background, guitar, rhythm/bass, drums, vocals)
+ typedef std::map<std::string,std::string> Music;
+ Music music; ///< music files (background, guitar, rhythm/bass, drums, vocals)
std::string cover; ///< cd cover
std::string background; ///< background image
std::string video; ///< video
|