From 0475b2a045780d2a8ab4ce439a09cf13a52027ef Mon Sep 17 00:00:00 2001 From: in1tiate <32779090+in1tiate@users.noreply.github.com> Date: Sun, 26 May 2024 15:31:15 -0500 Subject: [PATCH 1/7] Fix invalid file paths causing unexpected behavior --- src/animationloader.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/animationloader.cpp b/src/animationloader.cpp index 5f57cbe..ae7bfe0 100644 --- a/src/animationloader.cpp +++ b/src/animationloader.cpp @@ -25,6 +25,17 @@ void AnimationLoader::load(const QString &fileName) { return; } + else if (fileName == QObject::tr("Invalid File")) + { + // Set the image to a null pixmap if it's invalid + stopLoading(); + m_size = QSize(1, 1); + m_frames.clear(); + m_frames.append(AnimationFrame(QPixmap(), 0)); + m_frame_count = 1; + m_loop_count = 0; + return; + } stopLoading(); m_file_name = fileName; QImageReader *reader = new QImageReader; From da3b872beb7959eae4c1574e0b1b0a8ae34cb062 Mon Sep 17 00:00:00 2001 From: in1tiate <32779090+in1tiate@users.noreply.github.com> Date: Mon, 27 May 2024 10:22:01 -0500 Subject: [PATCH 2/7] just hide the layer in courtroom.cpp --- src/animationloader.cpp | 11 ----------- src/courtroom.cpp | 9 ++++++++- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/animationloader.cpp b/src/animationloader.cpp index ae7bfe0..5f57cbe 100644 --- a/src/animationloader.cpp +++ b/src/animationloader.cpp @@ -25,17 +25,6 @@ void AnimationLoader::load(const QString &fileName) { return; } - else if (fileName == QObject::tr("Invalid File")) - { - // Set the image to a null pixmap if it's invalid - stopLoading(); - m_size = QSize(1, 1); - m_frames.clear(); - m_frames.append(AnimationFrame(QPixmap(), 0)); - m_frame_count = 1; - m_loop_count = 0; - return; - } stopLoading(); m_file_name = fileName; QImageReader *reader = new QImageReader; diff --git a/src/courtroom.cpp b/src/courtroom.cpp index ce4b982..cf6a64b 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -4526,7 +4526,14 @@ void Courtroom::set_scene(bool show_desk, const QString f_side) QPair desk_pair = ao_app->get_pos_path(f_side, true); ui_vp_background->loadAndPlayAnimation(bg_pair.first); - ui_vp_desk->loadAndPlayAnimation(desk_pair.first); + if (file_exists(ao_app->get_image_suffix(ao_app->get_background_path(desk_pair.first)))) + { + ui_vp_desk->loadAndPlayAnimation(desk_pair.first); + } + else + { + show_desk = false; + } double scale = double(ui_viewport->height()) / double(ui_vp_background->frameSize().height()); QSize scaled_size = ui_vp_background->frameSize() * scale; From 83715f4276ee4eb705b77a80e7484d7e7236fffe Mon Sep 17 00:00:00 2001 From: in1tiate <32779090+in1tiate@users.noreply.github.com> Date: Mon, 27 May 2024 10:33:06 -0500 Subject: [PATCH 3/7] fix effects continuing to be displayed when they shouldn't --- src/courtroom.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index cf6a64b..9c916ea 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -1436,6 +1436,7 @@ void Courtroom::set_background(QString p_background, bool display) ui_vp_player_char->stopPlayback(); ui_vp_sideplayer_char->stopPlayback(); ui_vp_effect->stopPlayback(); + ui_vp_effect->hide(); ui_vp_message->hide(); ui_vp_chatbox->setVisible(chatbox_always_show); // Show it if chatbox always shows @@ -2746,6 +2747,7 @@ void Courtroom::display_character() ui_vp_speedlines->hide(); ui_vp_player_char->stopPlayback(); ui_vp_effect->stopPlayback(); + ui_vp_effect->hide(); // Clear all looping sfx to prevent obnoxiousness sfx_player->stopAllLoopingStream(); // Hide the message and chatbox and handle the emotes From 37f103e2c27015dc311371d621097f0b3b523b70 Mon Sep 17 00:00:00 2001 From: in1tiate <32779090+in1tiate@users.noreply.github.com> Date: Thu, 30 May 2024 15:13:35 -0500 Subject: [PATCH 4/7] restore old bg fallback behavior --- src/courtroom.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 9c916ea..f8becec 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -4527,7 +4527,21 @@ void Courtroom::set_scene(bool show_desk, const QString f_side) QPair bg_pair = ao_app->get_pos_path(f_side); QPair desk_pair = ao_app->get_pos_path(f_side, true); - ui_vp_background->loadAndPlayAnimation(bg_pair.first); + if (file_exists(ao_app->get_image_suffix(ao_app->get_background_path(bg_pair.first)))) + { + ui_vp_background->show(); + ui_vp_background->loadAndPlayAnimation(bg_pair.first); + } + else if (file_exists(ao_app->get_image_suffix(ao_app->get_background_path("wit")))) + { + ui_vp_background->show(); + ui_vp_background->loadAndPlayAnimation(ao_app->get_image_suffix(ao_app->get_background_path("wit"))); + } + else + { + ui_vp_background->hide(); + } + if (file_exists(ao_app->get_image_suffix(ao_app->get_background_path(desk_pair.first)))) { ui_vp_desk->loadAndPlayAnimation(desk_pair.first); From 5bc82b0d4f14a2e8cfa8c346c8ad1d2d37fd650c Mon Sep 17 00:00:00 2001 From: in1tiate <32779090+in1tiate@users.noreply.github.com> Date: Fri, 31 May 2024 10:35:58 -0500 Subject: [PATCH 5/7] restore accurate slide bookending --- src/courtroom.cpp | 12 ++++++++---- src/courtroom.h | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index f8becec..c9c22f1 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -514,7 +514,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app) connect(ui_vp_evidence_display, &AOEvidenceDisplay::show_evidence_details, this, &Courtroom::show_evidence); - connect(transition_animation_group, &QParallelAnimationGroup::finished, this, &Courtroom::post_transition_cleanup); + connect(transition_animation_group, &QParallelAnimationGroup::finished, this, &Courtroom::finish_transition); set_widgets(); @@ -3110,13 +3110,17 @@ void Courtroom::do_transition(QString p_desk_mod, QString oldPosId, QString newP ui_vp_sideplayer_char->hide(); } - transition_animation_group->start(); + QTimer::singleShot(TRANSITION_BOOKEND_DELAY, transition_animation_group, SLOT(start())); +} + +void Courtroom::finish_transition() +{ + transition_animation_group->clear(); + QTimer::singleShot(TRANSITION_BOOKEND_DELAY, this, SLOT(post_transition_cleanup())); } void Courtroom::post_transition_cleanup() { - transition_animation_group->clear(); - for (kal::CharacterAnimationLayer *layer : qAsConst(ui_vp_char_list)) { bool is_visible = layer->isVisible(); diff --git a/src/courtroom.h b/src/courtroom.h index a7ca235..b3b34c6 100644 --- a/src/courtroom.h +++ b/src/courtroom.h @@ -983,5 +983,6 @@ private Q_SLOTS: // After attempting to play a transition animation, clean up the viewport // objects for everyone else and continue the IC processing callstack + void finish_transition(); void post_transition_cleanup(); }; From 5af9dce21481e1d402df701b91593ccde4049c4b Mon Sep 17 00:00:00 2001 From: in1tiate <32779090+in1tiate@users.noreply.github.com> Date: Sat, 1 Jun 2024 13:54:57 -0500 Subject: [PATCH 6/7] remove bizarre obsolete delay from evidence present logic --- src/aoevidencedisplay.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/aoevidencedisplay.cpp b/src/aoevidencedisplay.cpp index 27afdb6..47bcf65 100644 --- a/src/aoevidencedisplay.cpp +++ b/src/aoevidencedisplay.cpp @@ -52,8 +52,6 @@ void AOEvidenceDisplay::show_evidence(int p_index, QString p_evidence_image, boo ui_prompt_details->setIconSize(f_pixmap.rect().size()); ui_prompt_details->resize(f_pixmap.rect().size()); ui_prompt_details->move(icon_dimensions.x, icon_dimensions.y); - m_evidence_movie->setMinimumDurationPerFrame(320); - m_evidence_movie->setMaximumDurationPerFrame(1000); m_evidence_movie->setPlayOnce(true); m_evidence_movie->loadAndPlayAnimation(gif_name, ""); m_sfx_player->findAndPlaySfx(ao_app->get_court_sfx("evidence_present")); From a714bacd1aba3e54bf485580d112b42385788c50 Mon Sep 17 00:00:00 2001 From: TrickyLeifa Date: Mon, 3 Jun 2024 18:11:17 +0200 Subject: [PATCH 7/7] Added screen slide timer * Added screen slide timer * Added so that the animation becomes interruptible. --- CMakeLists.txt | 1 + src/courtroom.cpp | 27 ++++++------- src/courtroom.h | 12 ++---- src/screenslidetimer.cpp | 86 ++++++++++++++++++++++++++++++++++++++++ src/screenslidetimer.h | 46 +++++++++++++++++++++ 5 files changed, 149 insertions(+), 23 deletions(-) create mode 100644 src/screenslidetimer.cpp create mode 100644 src/screenslidetimer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b1f2529..6fabdcf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,6 +102,7 @@ add_executable(Attorney_Online src/widgets/server_editor_dialog.cpp src/widgets/server_editor_dialog.h data.qrc + src/screenslidetimer.h src/screenslidetimer.cpp ) set_target_properties(Attorney_Online PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin") diff --git a/src/courtroom.cpp b/src/courtroom.cpp index c9c22f1..c2c3421 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -111,6 +111,10 @@ Courtroom::Courtroom(AOApplication *p_ao_app) ui_vp_objection->setAttribute(Qt::WA_TransparentForMouseEvents); ui_vp_objection->setObjectName("ui_vp_objection"); + m_screenshake_anim_group = new QParallelAnimationGroup(this); + + m_screenslide_timer = new kal::ScreenSlideTimer(this); + ui_ic_chatlog = new QTextEdit(this); ui_ic_chatlog->setReadOnly(true); ui_ic_chatlog->setObjectName("ui_ic_chatlog"); @@ -514,7 +518,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app) connect(ui_vp_evidence_display, &AOEvidenceDisplay::show_evidence_details, this, &Courtroom::show_evidence); - connect(transition_animation_group, &QParallelAnimationGroup::finished, this, &Courtroom::finish_transition); + connect(m_screenslide_timer, &kal::ScreenSlideTimer::finished, this, &Courtroom::post_transition_cleanup); set_widgets(); @@ -2502,6 +2506,7 @@ void Courtroom::unpack_chatmessage(QStringList p_contents) anim_state = 0; evidence_presented = false; ui_vp_objection->stopPlayback(); + m_screenslide_timer->stop(); chat_tick_timer->stop(); ui_vp_evidence_display->reset(); // This chat msg is not objection so we're not waiting on the objection animation to finish to display the character. @@ -2947,8 +2952,8 @@ void Courtroom::do_screenshake() // would return to its "final frame" properly. This properly resets all UI // elements without having to bother keeping track of "origin" positions. // Works great with the chat text being detached from the chat box! - screenshake_animation_group->setCurrentTime(screenshake_animation_group->duration()); - screenshake_animation_group->clear(); + m_screenshake_anim_group->setCurrentTime(m_screenshake_anim_group->duration()); + m_screenshake_anim_group->clear(); const QList &affected_list = {ui_vp_background, ui_vp_player_char, ui_vp_sideplayer_char, ui_vp_chatbox}; @@ -2975,10 +2980,10 @@ void Courtroom::do_screenshake() } screenshake_animation->setEndValue(pos_default); screenshake_animation->setEasingCurve(QEasingCurve::Linear); - screenshake_animation_group->addAnimation(screenshake_animation); + m_screenshake_anim_group->addAnimation(screenshake_animation); } - screenshake_animation_group->start(); + m_screenshake_anim_group->start(); } void Courtroom::do_transition(QString p_desk_mod, QString oldPosId, QString newPosId) @@ -3020,7 +3025,7 @@ void Courtroom::do_transition(QString p_desk_mod, QString oldPosId, QString newP ui_vp_dummy_char->setStyleSheet("background-color:rgba(255, 0, 0, 128);"); ui_vp_sidedummy_char->setStyleSheet("background-color:rgba(0, 255, 0, 128);"); - qDebug() << "STARTING TRANSITION, CURRENT TIME:" << transition_animation_group->currentTime(); + qDebug() << "STARTING TRANSITION"; #endif set_scene(p_desk_mod.toInt(), oldPosId); @@ -3039,7 +3044,7 @@ void Courtroom::do_transition(QString p_desk_mod, QString oldPosId, QString newP transition_animation->setEasingCurve(QEasingCurve::InOutCubic); transition_animation->setStartValue(QPoint(-scaled_old_pos.x(), 0)); transition_animation->setEndValue(QPoint(-scaled_new_pos.x(), 0)); - transition_animation_group->addAnimation(transition_animation); + m_screenslide_timer->addAnimation(transition_animation); } auto calculate_offset_and_setup_layer = [&, this](kal::CharacterAnimationLayer *layer, QPoint newPos, QString rawOffset) { @@ -3110,13 +3115,7 @@ void Courtroom::do_transition(QString p_desk_mod, QString oldPosId, QString newP ui_vp_sideplayer_char->hide(); } - QTimer::singleShot(TRANSITION_BOOKEND_DELAY, transition_animation_group, SLOT(start())); -} - -void Courtroom::finish_transition() -{ - transition_animation_group->clear(); - QTimer::singleShot(TRANSITION_BOOKEND_DELAY, this, SLOT(post_transition_cleanup())); + m_screenslide_timer->start(); } void Courtroom::post_transition_cleanup() diff --git a/src/courtroom.h b/src/courtroom.h index b3b34c6..a01102e 100644 --- a/src/courtroom.h +++ b/src/courtroom.h @@ -23,6 +23,7 @@ #include "file_functions.h" #include "hardware_functions.h" #include "lobby.h" +#include "screenslidetimer.h" #include "scrolltext.h" #include "widgets/aooptionsdialog.h" @@ -310,9 +311,9 @@ private: int maximumMessages = 0; - QParallelAnimationGroup *screenshake_animation_group = new QParallelAnimationGroup; + QParallelAnimationGroup *m_screenshake_anim_group; - QParallelAnimationGroup *transition_animation_group = new QParallelAnimationGroup; + kal::ScreenSlideTimer *m_screenslide_timer; bool next_character_is_not_special = false; // If true, write the // next character as it is. @@ -446,12 +447,6 @@ private: QString m_chatmessage[MS_MAXIMUM]; QString m_previous_chatmessage[MS_MAXIMUM]; - /** - * @brief The amount of time to wait at the start and end of slide - * animations - */ - static const int TRANSITION_BOOKEND_DELAY = 300; - QString additive_previous; // char id, muted or not @@ -983,6 +978,5 @@ private Q_SLOTS: // After attempting to play a transition animation, clean up the viewport // objects for everyone else and continue the IC processing callstack - void finish_transition(); void post_transition_cleanup(); }; diff --git a/src/screenslidetimer.cpp b/src/screenslidetimer.cpp new file mode 100644 index 0000000..2bfd0cd --- /dev/null +++ b/src/screenslidetimer.cpp @@ -0,0 +1,86 @@ +#include "screenslidetimer.h" + +#include + +namespace kal +{ +ScreenSlideTimer::ScreenSlideTimer(QObject *parent) + : QObject(parent) +{ + m_pause = new QTimer(this); + m_pause->setInterval(TRANSITION_BOOKEND_DELAY); + m_pause->setSingleShot(true); + + m_group = new QParallelAnimationGroup(this); + + connect(m_pause, &QTimer::timeout, this, &ScreenSlideTimer::startNextState); + connect(m_group, &QParallelAnimationGroup::finished, this, &ScreenSlideTimer::startNextState); +} + +ScreenSlideTimer::~ScreenSlideTimer() +{ + m_group->disconnect(this); + m_pause->disconnect(this); + stop(); +} + +void ScreenSlideTimer::addAnimation(QAbstractAnimation *animation) +{ + if (m_running) + { + qWarning() << "Cannot add animations while transition is in progress"; + return; + } + m_group->addAnimation(animation); +} + +void ScreenSlideTimer::start() +{ + if (m_running) + { + qWarning() << "Transition already in progress"; + return; + } + m_running = true; + startNextState(); +} + +void ScreenSlideTimer::stop() +{ + if (m_running) + { + m_running = false; + m_state = NoTransition; + m_group->stop(); + m_group->clear(); + m_pause->stop(); + } +} + +void ScreenSlideTimer::startNextState() +{ + switch (m_state) + { + case NoTransition: + m_state = PreTransition; + Q_EMIT started(); + m_pause->start(); + return; + + case PreTransition: + m_state = GroupTransition; + m_group->start(); + break; + + case GroupTransition: + m_state = PostTransition; + m_pause->start(); + break; + + case PostTransition: + stop(); + Q_EMIT finished(); + break; + } +} +} // namespace kal diff --git a/src/screenslidetimer.h b/src/screenslidetimer.h new file mode 100644 index 0000000..c2bf7a8 --- /dev/null +++ b/src/screenslidetimer.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include +#include + +namespace kal +{ +class ScreenSlideTimer : public QObject +{ + Q_OBJECT + +public: + static const int TRANSITION_BOOKEND_DELAY = 300; + + explicit ScreenSlideTimer(QObject *parent = nullptr); + virtual ~ScreenSlideTimer(); + + void addAnimation(QAbstractAnimation *animation); + +public Q_SLOTS: + void start(); + void stop(); + +Q_SIGNALS: + void started(); + void finished(); + +private: + enum TransitionState + { + NoTransition, + PreTransition, + GroupTransition, + PostTransition, + }; + + bool m_running = false; + TransitionState m_state = NoTransition; + QParallelAnimationGroup *m_group; + QTimer *m_pause; + +private Q_SLOTS: + void startNextState(); +}; +} // namespace kal