From ab30cca586a05506c3cfb502cee53957409242e8 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Sat, 14 Sep 2019 19:50:46 +0300 Subject: [PATCH] Use a ticker and QImageReader instead of QMovie Issue: absolutely fucking broken, needs shittons of fixing or ditching. Might not be that efficient, anyway. --- include/aocharmovie.h | 16 ++-- src/aocharmovie.cpp | 175 +++++++++++++++++------------------------- 2 files changed, 82 insertions(+), 109 deletions(-) diff --git a/include/aocharmovie.h b/include/aocharmovie.h index f54f510..65ab79f 100644 --- a/include/aocharmovie.h +++ b/include/aocharmovie.h @@ -1,7 +1,7 @@ #ifndef AOCHARMOVIE_H #define AOCHARMOVIE_H -#include +#include #include #include #include @@ -21,20 +21,24 @@ public: void play_talking(QString p_char, QString p_emote); void play_idle(QString p_char, QString p_emote); - void set_flipped(bool p_flipped) {m_flipped = p_flipped;} + void set_frame(QImage image); void stop(); + void set_flipped(bool p_flipped) {m_flipped = p_flipped;} + void move(int ax, int ay); void combo_resize(int w, int h); + private: AOApplication *ao_app; - QMovie *m_movie; - QVector movie_frames; + QImageReader *m_reader; QTimer *preanim_timer; + QTimer *ticker; + QString last_path; const int time_mod = 60; @@ -50,8 +54,8 @@ signals: void done(); private slots: - void frame_change(int n_frame); - void timer_done(); + void preanim_done(); + void movie_ticker(); }; #endif // AOCHARMOVIE_H diff --git a/src/aocharmovie.cpp b/src/aocharmovie.cpp index ac12f63..8004a54 100644 --- a/src/aocharmovie.cpp +++ b/src/aocharmovie.cpp @@ -7,14 +7,15 @@ AOCharMovie::AOCharMovie(QWidget *p_parent, AOApplication *p_ao_app) : QLabel(p_parent) { ao_app = p_ao_app; - - m_movie = new QMovie(this); - preanim_timer = new QTimer(this); preanim_timer->setSingleShot(true); - connect(m_movie, SIGNAL(frameChanged(int)), this, SLOT(frame_change(int))); - connect(preanim_timer, SIGNAL(timeout()), this, SLOT(timer_done())); + ticker = new QTimer(this); + ticker->setSingleShot(true); + connect(ticker, SIGNAL(timeout()), this, SLOT(movie_ticker())); + +// connect(m_movie, SIGNAL(frameChanged(int)), this, SLOT(frame_change(int))); + connect(preanim_timer, SIGNAL(timeout()), this, SLOT(preanim_done())); } void AOCharMovie::play(QString p_char, QString p_emote, QString emote_prefix) @@ -37,126 +38,61 @@ void AOCharMovie::play(QString p_char, QString p_emote, QString emote_prefix) } } - m_movie->stop(); - m_movie->setFileName(emote_path); + this->clear(); + m_reader = new QImageReader(emote_path); - QImageReader *reader = new QImageReader(emote_path); - - movie_frames.clear(); - QImage f_image = reader->read(); - while (!f_image.isNull()) - { - if (m_flipped) - movie_frames.append(f_image.mirrored(true, false)); - else - movie_frames.append(f_image); - f_image = reader->read(); - } - - delete reader; + QImage f_image = m_reader->read(); +// while (!f_image.isNull()) +// { +// if (m_flipped) +// movie_frames.append(f_image.mirrored(true, false)); +// else +// movie_frames.append(f_image); +// f_image = reader->read(); +// } +// delete m_reader; this->show(); - m_movie->start(); + qDebug() << "Setting image to " << f_image; + this->set_frame(f_image); + if (m_reader->supportsAnimation()) + ticker->start(m_reader->nextImageDelay()); } void AOCharMovie::play_pre(QString p_char, QString p_emote, int duration) { - QString emote_path = ao_app->get_character_path(p_char, p_emote); - - m_movie->stop(); - this->clear(); - m_movie->setFileName(emote_path); - m_movie->jumpToFrame(0); - - int full_duration = duration * time_mod; - int real_duration = 0; - - play_once = false; - - for (int n_frame = 0 ; n_frame < m_movie->frameCount() ; ++n_frame) - { - qDebug() << "frame " << n_frame << " delay of " << m_movie->nextFrameDelay(); - real_duration += m_movie->nextFrameDelay(); - m_movie->jumpToFrame(n_frame + 1); - } - -#ifdef DEBUG_GIF - qDebug() << "full_duration: " << full_duration; - qDebug() << "real_duration: " << real_duration; -#endif - - double percentage_modifier = 100.0; - - if (real_duration != 0 && duration > 0) - { - double modifier = full_duration / static_cast(real_duration); - percentage_modifier = 100 / modifier; - - if (percentage_modifier > 100.0) - percentage_modifier = 100.0; - } - -#ifdef DEBUG_GIF - qDebug() << "% mod: " << percentage_modifier; -#endif - - if (full_duration == 0 || full_duration >= real_duration) - { - play_once = true; - } - else - { - play_once = false; - preanim_timer->start(full_duration); - } - - - m_movie->setSpeed(static_cast(percentage_modifier)); +// QString emote_path = ao_app->get_character_path(p_char, p_emote); + play_once = true; play(p_char, p_emote, ""); } void AOCharMovie::play_talking(QString p_char, QString p_emote) { play_once = false; - m_movie->setSpeed(100); play(p_char, p_emote, "(b)"); } void AOCharMovie::play_idle(QString p_char, QString p_emote) { play_once = false; - m_movie->setSpeed(100); play(p_char, p_emote, "(a)"); } void AOCharMovie::stop() { //for all intents and purposes, stopping is the same as hiding. at no point do we want a frozen gif to display - m_movie->stop(); + ticker->stop(); preanim_timer->stop(); this->hide(); } -void AOCharMovie::combo_resize(int w, int h) +void AOCharMovie::set_frame(QImage image) { - QSize f_size(w, h); - this->resize(f_size); - m_movie->setScaledSize(f_size); -} - -void AOCharMovie::move(int ax, int ay) -{ - x = ax; - y = ay; - QLabel::move(x, y); -} - -void AOCharMovie::frame_change(int n_frame) -{ - - if (movie_frames.size() > n_frame) - { - QPixmap f_pixmap = QPixmap::fromImage(movie_frames.at(n_frame)); + QPixmap f_pixmap; + if(m_flipped) + f_pixmap = QPixmap::fromImage(image.mirrored(true, false)); + else + f_pixmap = QPixmap::fromImage(image); auto aspect_ratio = Qt::KeepAspectRatio; if (f_pixmap.size().width() > f_pixmap.size().height()) @@ -168,17 +104,50 @@ void AOCharMovie::frame_change(int n_frame) this->setPixmap(f_pixmap.scaled(this->width(), this->height(), aspect_ratio, Qt::FastTransformation)); QLabel::move(x + (this->width() - this->pixmap()->width())/2, y); - } - - if (m_movie->frameCount() - 1 == n_frame && play_once) - { - preanim_timer->start(m_movie->nextFrameDelay()); - m_movie->stop(); - } } -void AOCharMovie::timer_done() +void AOCharMovie::combo_resize(int w, int h) { + QSize f_size(w, h); + this->resize(f_size); +// m_reader->setScaledSize(f_size); +} +void AOCharMovie::move(int ax, int ay) +{ + x = ax; + y = ay; + QLabel::move(x, y); +} + +void AOCharMovie::movie_ticker() +{ + if(m_reader->format() != "gif") + ticker->start(m_reader->nextImageDelay()); + if(m_reader->currentImageNumber() == -1) + { + if(play_once) + { + preanim_done(); + return; + } + else + m_reader->jumpToImage(0); //Loop back + } + QImage f_image = m_reader->read(); + if(f_image.isNull()) + { + qDebug() << "Animated image error on frame" << m_reader->currentImageNumber() << m_reader->errorString(); + stop(); + return; + } + this->set_frame(f_image); + qDebug() << m_reader->format() << "frame" << m_reader->nextImageDelay() << m_reader->currentImageNumber() << m_reader->imageCount(); + if(m_reader->format() == "gif") + ticker->start(m_reader->nextImageDelay()); +} + +void AOCharMovie::preanim_done() +{ done(); }