diff options
| -rw-r--r-- | .github/workflows/build.yml | 5 | ||||
| -rw-r--r-- | include/aoapplication.h | 35 | ||||
| -rw-r--r-- | include/aoblipplayer.h | 3 | ||||
| -rw-r--r-- | include/aoemotepreview.h | 32 | ||||
| -rw-r--r-- | include/aomusicplayer.h | 2 | ||||
| -rw-r--r-- | include/aooptionsdialog.h | 2 | ||||
| -rw-r--r-- | include/aosfxplayer.h | 4 | ||||
| -rw-r--r-- | include/courtroom.h | 19 | ||||
| -rw-r--r-- | include/hardware_functions.h | 4 | ||||
| -rw-r--r-- | src/aoblipplayer.cpp | 9 | ||||
| -rw-r--r-- | src/aoemotepreview.cpp | 44 | ||||
| -rw-r--r-- | src/aomusicplayer.cpp | 12 | ||||
| -rw-r--r-- | src/aooptionsdialog.cpp | 19 | ||||
| -rw-r--r-- | src/aosfxplayer.cpp | 12 | ||||
| -rw-r--r-- | src/courtroom.cpp | 169 | ||||
| -rw-r--r-- | src/emotes.cpp | 86 | ||||
| -rw-r--r-- | src/hardware_functions.cpp | 10 | ||||
| -rw-r--r-- | src/packet_distribution.cpp | 92 | ||||
| -rw-r--r-- | src/text_file_functions.cpp | 6 |
19 files changed, 424 insertions, 141 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f29872b..fefdc54 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -73,7 +73,7 @@ jobs: chmod +x get_libs.sh ./get_libs.sh 1.2.12 1.6.37 cd ../.. - qmake CONFIG+=install_ok QT_PLATFORM=${{matrix.platform}} + qmake CONFIG+=install_ok QMAKE_CXXFLAGS+="-fno-sized-deallocation" QT_PLATFORM=${{matrix.platform}} ${{steps.qt.outputs.make}} qmake_all ${{steps.qt.outputs.make}} ${{steps.qt.outputs.make}} INSTALL_ROOT="${{steps.qt.outputs.installdir}}" install @@ -222,9 +222,12 @@ jobs: shell: bash run: | cp ../scripts/launch.sh . + mkdir imageformats + cp ../QtApng/plugins/imageformats/libqapng.so ./imageformats/libqapng.so chmod +x launch.sh chmod +x Attorney_Online tar -cf Attorney_Online.tar ./* + rm -rf imageformats rm *.so rm *.sh rm Attorney_Online diff --git a/include/aoapplication.h b/include/aoapplication.h index cf9eb2b..c3b7550 100644 --- a/include/aoapplication.h +++ b/include/aoapplication.h @@ -88,22 +88,22 @@ public: /////////////////server metadata////////////////// - bool yellow_text_enabled = false; - bool prezoom_enabled = false; - bool flipping_enabled = false; - bool custom_objection_enabled = false; - bool desk_mod_enabled = false; - bool evidence_enabled = false; - bool cccc_ic_support_enabled = false; - bool arup_enabled = false; - bool casing_alerts_enabled = false; - bool modcall_reason_enabled = false; - bool looping_sfx_support_enabled = false; - bool additive_enabled = false; - bool effects_enabled = false; - bool y_offset_enabled = false; - bool expanded_desk_mods_enabled = false; - bool auth_packet_enabled = false; + bool yellow_text_supported = false; + bool prezoom_supported = false; + bool flipping_supported = false; + bool custom_objection_supported = false; + bool desk_mod_supported = false; + bool evidence_supported = false; + bool cccc_ic_supported = false; + bool arup_supported = false; + bool casing_alerts_supported = false; + bool modcall_reason_supported = false; + bool looping_sfx_supported = false; + bool additive_text_supported = false; + bool effects_supported = false; + bool y_offset_supported = false; + bool expanded_desk_mods_supported = false; + bool auth_packet_supported = false; ///////////////loading info/////////////////// @@ -204,6 +204,9 @@ public: // Returns the value of default_blip in config.ini int get_default_blip(); + // Returns the value of suppress_audio in config.ini + int get_default_suppress_audio(); + // Returns the value if objections interrupt and skip the message queue // from the config.ini. bool is_instant_objection_enabled(); diff --git a/include/aoblipplayer.h b/include/aoblipplayer.h index a11e29d..ea2dcd3 100644 --- a/include/aoblipplayer.h +++ b/include/aoblipplayer.h @@ -18,6 +18,7 @@ public: void set_blips(QString p_sfx); void blip_tick(); void set_volume(int p_volume); + void set_muted(bool toggle); int m_cycle = 0; @@ -26,6 +27,8 @@ private: AOApplication *ao_app; qreal m_volume; + bool m_muted = false; + void set_volume_internal(qreal p_volume); HSTREAM m_stream_list[5]; diff --git a/include/aoemotepreview.h b/include/aoemotepreview.h new file mode 100644 index 0000000..315371b --- /dev/null +++ b/include/aoemotepreview.h @@ -0,0 +1,32 @@ +#ifndef AOEMOTEPREVIEW_H +#define AOEMOTEPREVIEW_H + +#include "aolayer.h" +#include <QWidget> + +class AOEmotePreview : public QWidget +{ + Q_OBJECT +public: + AOEmotePreview(QWidget *parent = nullptr, + AOApplication *p_ao_app = nullptr); + + void set_widgets(); + void play(QString emote, QString char_name, bool flipped = false, int self_offset = 0, int self_offset_v = 0); +private: + AOApplication *ao_app; + QWidget *ui_viewport; + BackgroundLayer *ui_vp_background; + SplashLayer *ui_vp_speedlines; + CharLayer *ui_vp_player_char; + BackgroundLayer *ui_vp_desk; + + QLabel *ui_size_label; + + QString m_emote = ""; + QString m_char = ""; +protected: + void resizeEvent(QResizeEvent *); +}; + +#endif // AOEMOTEPREVIEW_H diff --git a/include/aomusicplayer.h b/include/aomusicplayer.h index d00ab8e..037525f 100644 --- a/include/aomusicplayer.h +++ b/include/aomusicplayer.h @@ -20,6 +20,7 @@ public: virtual ~AOMusicPlayer(); void set_volume(int p_value, int channel = -1); void set_looping(bool toggle, int channel = 0); + void set_muted(bool toggle); const int m_channelmax = 4; @@ -39,6 +40,7 @@ private: AOApplication *ao_app; bool m_looping = false; + bool m_muted = false; int m_volume[4] = {0, 0, 0, 0}; // Channel 0 = music diff --git a/include/aooptionsdialog.h b/include/aooptionsdialog.h index 2180379..cb9b71b 100644 --- a/include/aooptionsdialog.h +++ b/include/aooptionsdialog.h @@ -127,8 +127,10 @@ private: QLabel *ui_music_volume_lbl; QSpinBox *ui_sfx_volume_spinbox; QSpinBox *ui_blips_volume_spinbox; + QSpinBox *ui_suppress_audio_spinbox; QLabel *ui_sfx_volume_lbl; QLabel *ui_blips_volume_lbl; + QLabel *ui_suppress_audio_lbl; QFrame *ui_volume_blip_divider; QSpinBox *ui_bliprate_spinbox; QLabel *ui_bliprate_lbl; diff --git a/include/aosfxplayer.h b/include/aosfxplayer.h index 7597636..077a7ef 100644 --- a/include/aosfxplayer.h +++ b/include/aosfxplayer.h @@ -20,14 +20,16 @@ public: void stop(int channel = -1); void set_volume(qreal p_volume); void set_looping(bool toggle, int channel = -1); + void set_muted(bool toggle); int m_channel = 0; - + int get_volume() { return m_volume * 100; }; private: QWidget *m_parent; AOApplication *ao_app; qreal m_volume = 0; bool m_looping = true; + bool m_muted = false; void set_volume_internal(qreal p_volume); const int m_channelmax = 5; diff --git a/include/courtroom.h b/include/courtroom.h index 73ef6fb..0c53c95 100644 --- a/include/courtroom.h +++ b/include/courtroom.h @@ -24,6 +24,7 @@ #include "lobby.h" #include "scrolltext.h" #include "eventfilters.h" +#include "aoemotepreview.h" #include <QCheckBox> #include <QCloseEvent> @@ -51,6 +52,9 @@ #include <QMessageBox> #include <QParallelAnimationGroup> #include <QPropertyAnimation> +#if QT_VERSION > QT_VERSION_CHECK(5, 10, 0) +#include <QRandomGenerator> //added in Qt 5.10 +#endif #include <QRegExp> #include <QScrollBar> #include <QTextBoundaryFinder> @@ -69,6 +73,8 @@ class Courtroom : public QMainWindow { public: explicit Courtroom(AOApplication *p_ao_app); + void update_audio_volume(); + void append_char(char_type p_char) { char_list.append(p_char); } void append_evidence(evi_type p_evi) { evidence_list.append(p_evi); } void append_music(QString f_music) { music_list.append(f_music); } @@ -338,6 +344,9 @@ public: private: AOApplication *ao_app; + // Percentage of audio that is suppressed when client is not in focus + int suppress_audio = 0; + int m_courtroom_width = 714; int m_courtroom_height = 668; @@ -685,6 +694,9 @@ private: AOButton *ui_emote_left; AOButton *ui_emote_right; + QMenu *emote_menu; + AOEmotePreview *emote_preview; + QComboBox *ui_emote_dropdown; QComboBox *ui_pos_dropdown; AOButton *ui_pos_remove; @@ -915,6 +927,8 @@ private slots: void on_custom_objection_clicked(); void show_custom_objection_menu(const QPoint &pos); + void show_emote_menu(const QPoint &pos); + void on_realization_clicked(); void on_screenshake_clicked(); @@ -988,10 +1002,15 @@ private slots: void on_casing_clicked(); + void on_application_state_changed(Qt::ApplicationState state); + void ping_server(); // Proceed to parse the oldest chatmessage and remove it from the stack void chatmessage_dequeue(); + + void preview_emote(QString emote); + void update_emote_preview(); }; #endif // COURTROOM_H diff --git a/include/hardware_functions.h b/include/hardware_functions.h index 3fcb27c..05d3f2a 100644 --- a/include/hardware_functions.h +++ b/include/hardware_functions.h @@ -5,6 +5,10 @@ #include <stdio.h> +#ifdef ANDROID +#include <QtAndroidExtras/QtAndroid> +#endif + QString get_hdid(); #endif // HARDWARE_FUNCTIONS_H diff --git a/src/aoblipplayer.cpp b/src/aoblipplayer.cpp index 307a0bd..5dc2467 100644 --- a/src/aoblipplayer.cpp +++ b/src/aoblipplayer.cpp @@ -37,6 +37,12 @@ void AOBlipPlayer::blip_tick() BASS_ChannelPlay(f_stream, false); } +void AOBlipPlayer::set_muted(bool toggle) +{ + m_muted = toggle; + set_volume_internal(m_volume); +} + void AOBlipPlayer::set_volume(int p_value) { m_volume = static_cast<qreal>(p_value) / 100; @@ -45,7 +51,8 @@ void AOBlipPlayer::set_volume(int p_value) void AOBlipPlayer::set_volume_internal(qreal p_value) { - float volume = static_cast<float>(p_value); + // If muted, volume will always be 0 + float volume = static_cast<float>(p_value) * !m_muted; for (int n_stream = 0; n_stream < 5; ++n_stream) { BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL, volume); diff --git a/src/aoemotepreview.cpp b/src/aoemotepreview.cpp new file mode 100644 index 0000000..5afeebd --- /dev/null +++ b/src/aoemotepreview.cpp @@ -0,0 +1,44 @@ +#include "aoemotepreview.h" + +AOEmotePreview::AOEmotePreview(QWidget *parent, AOApplication *p_ao_app) : QWidget(parent) +{ + ao_app = p_ao_app; + + ui_viewport = new QWidget(this); + ui_vp_player_char = new CharLayer(ui_viewport, ao_app); + ui_vp_player_char->setObjectName("ui_vp_player_char"); + ui_vp_player_char->masked = false; + ui_size_label = new QLabel(this); + ui_size_label->setObjectName("ui_size_label"); + setWindowFlag(Qt::WindowMinMaxButtonsHint, false); + setWindowFlag(Qt::Tool); + this->resize(256, 192); +} + +void AOEmotePreview::set_widgets() +{ + ui_viewport->resize(this->width(), this->height()); + + ui_vp_player_char->move_and_center(0, 0); + ui_vp_player_char->combo_resize(ui_viewport->width(), ui_viewport->height()); + + ui_size_label->setText(QString::number(this->width()) + "x" + QString::number(this->height())); +} + +void AOEmotePreview::play(QString emote, QString char_name, bool flipped, int self_offset, int self_offset_v) +{ + ui_vp_player_char->stop(); + ui_vp_player_char->set_flipped(flipped); + ui_vp_player_char->move_and_center(ui_viewport->width() * self_offset / 100, ui_viewport->height() * self_offset_v / 100); + ui_vp_player_char->load_image(emote, char_name, 0, false); + ui_vp_player_char->set_play_once(false); + m_emote = emote; + m_char = char_name; + setWindowTitle(char_name + ": " + emote); +} + +void AOEmotePreview::resizeEvent(QResizeEvent *) +{ + set_widgets(); + ui_vp_player_char->load_image(m_emote, m_char, 0, false); +} diff --git a/src/aomusicplayer.cpp b/src/aomusicplayer.cpp index 16db163..59cf4d2 100644 --- a/src/aomusicplayer.cpp +++ b/src/aomusicplayer.cpp @@ -159,10 +159,20 @@ void AOMusicPlayer::stop(int channel) BASS_ChannelStop(m_stream_list[channel]); } +void AOMusicPlayer::set_muted(bool toggle) +{ + m_muted = toggle; + // Update all volume based on the mute setting + for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) { + set_volume(m_volume[n_stream], n_stream); + } +} + void AOMusicPlayer::set_volume(int p_value, int channel) { m_volume[channel] = p_value; - float volume = m_volume[channel] / 100.0f; + // If muted, volume will always be 0 + float volume = (m_volume[channel] / 100.0f) * !m_muted; if (channel < 0) { for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) { BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL, diff --git a/src/aooptionsdialog.cpp b/src/aooptionsdialog.cpp index 1d1a5eb..18e2f71 100644 --- a/src/aooptionsdialog.cpp +++ b/src/aooptionsdialog.cpp @@ -596,6 +596,21 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) ui_blips_volume_spinbox); row += 1; + ui_suppress_audio_lbl = new QLabel(ui_audio_widget); + ui_suppress_audio_lbl->setText(tr("Suppress Audio:")); + ui_suppress_audio_lbl->setToolTip( + tr("How much of the volume to suppress when client is not in focus.")); + + ui_audio_layout->setWidget(row, QFormLayout::LabelRole, ui_suppress_audio_lbl); + + ui_suppress_audio_spinbox = new QSpinBox(ui_audio_widget); + ui_suppress_audio_spinbox->setMaximum(100); + ui_suppress_audio_spinbox->setSuffix("%"); + + ui_audio_layout->setWidget(row, QFormLayout::FieldRole, + ui_suppress_audio_spinbox); + + row += 1; ui_volume_blip_divider = new QFrame(ui_audio_widget); ui_volume_blip_divider->setFrameShape(QFrame::HLine); ui_volume_blip_divider->setFrameShadow(QFrame::Sunken); @@ -674,7 +689,7 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) // -- SERVER SUPPORTS CASING ui_casing_supported_lbl = new QLabel(ui_casing_widget); - if (ao_app->casing_alerts_enabled) + if (ao_app->casing_alerts_supported) ui_casing_supported_lbl->setText(tr("This server supports case alerts.")); else ui_casing_supported_lbl->setText( @@ -1192,6 +1207,7 @@ void AOOptionsDialog::update_values() { ui_music_volume_spinbox->setValue(ao_app->get_default_music()); ui_sfx_volume_spinbox->setValue(ao_app->get_default_sfx()); ui_blips_volume_spinbox->setValue(ao_app->get_default_blip()); + ui_suppress_audio_spinbox->setValue(ao_app->get_default_suppress_audio()); ui_bliprate_spinbox->setValue(ao_app->read_blip_rate()); ui_default_showname_textbox->setText(ao_app->get_default_showname()); @@ -1272,6 +1288,7 @@ void AOOptionsDialog::save_pressed() configini->setValue("default_music", ui_music_volume_spinbox->value()); configini->setValue("default_sfx", ui_sfx_volume_spinbox->value()); configini->setValue("default_blip", ui_blips_volume_spinbox->value()); + configini->setValue("suppress_audio", ui_suppress_audio_spinbox->value()); configini->setValue("blip_rate", ui_bliprate_spinbox->value()); configini->setValue("blank_blip", ui_blank_blips_cb->isChecked()); configini->setValue("looping_sfx", ui_loopsfx_cb->isChecked()); diff --git a/src/aosfxplayer.cpp b/src/aosfxplayer.cpp index fcdeb94..8d88667 100644 --- a/src/aosfxplayer.cpp +++ b/src/aosfxplayer.cpp @@ -60,15 +60,23 @@ void AOSfxPlayer::stop(int channel) BASS_ChannelStop(m_stream_list[channel]); } +void AOSfxPlayer::set_muted(bool toggle) +{ + m_muted = toggle; + // Update the audio volume + set_volume_internal(m_volume); +} + void AOSfxPlayer::set_volume(qreal p_value) { - m_volume = p_value / 100; + m_volume = p_value * 0.01; set_volume_internal(m_volume); } void AOSfxPlayer::set_volume_internal(qreal p_value) { - float volume = static_cast<float>(p_value); + // If muted, volume will always be 0 + float volume = static_cast<float>(p_value) * !m_muted; for (int n_stream = 0; n_stream < m_channelmax; ++n_stream) { BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL, volume); } diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 4581c2a..1884c7c 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -26,18 +26,18 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow() sfx_delay_timer->setSingleShot(true); music_player = new AOMusicPlayer(this, ao_app); - music_player->set_volume(0); + music_player->set_muted(true); connect(&music_player->music_watcher, &QFutureWatcher<QString>::finished, this, &Courtroom::update_ui_music_name, Qt::QueuedConnection); sfx_player = new AOSfxPlayer(this, ao_app); - sfx_player->set_volume(0); + sfx_player->set_muted(true); objection_player = new AOSfxPlayer(this, ao_app); - objection_player->set_volume(0); + objection_player->set_muted(true); blip_player = new AOBlipPlayer(this, ao_app); - blip_player->set_volume(0); + blip_player->set_muted(true); modcall_player = new AOSfxPlayer(this, ao_app); modcall_player->set_volume(50); @@ -209,8 +209,6 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow() ui_music_search->setPlaceholderText(tr("Search")); ui_music_search->setObjectName("ui_music_search"); - initialize_emotes(); - ui_pos_dropdown = new QComboBox(this); ui_pos_dropdown->view()->setTextElideMode(Qt::ElideLeft); ui_pos_dropdown->setObjectName("ui_pos_dropdown"); @@ -404,6 +402,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow() ui_evidence_button = new AOButton(this, ao_app); ui_evidence_button->setObjectName("ui_evidence_button"); + initialize_emotes(); initialize_evidence(); construct_char_select(); @@ -555,6 +554,9 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow() connect(ui_evidence_button, &AOButton::clicked, this, &Courtroom::on_evidence_button_clicked); + connect(qApp, QOverload<Qt::ApplicationState>::of(&QApplication::applicationStateChanged), this, + &Courtroom::on_application_state_changed); + connect(ui_vp_evidence_display, &AOEvidenceDisplay::show_evidence_details, this, &Courtroom::show_evidence); set_widgets(); @@ -562,6 +564,35 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow() set_char_select(); } +void Courtroom::on_application_state_changed(Qt::ApplicationState state) +{ + // Unsuppressed + suppress_audio = 0; + if (state != Qt::ApplicationActive) { + // Suppressed audio setting + suppress_audio = ao_app->get_default_suppress_audio(); + } + update_audio_volume(); +} + +void Courtroom::update_audio_volume() +{ + float remaining_percent = 1.0f - static_cast<float>(suppress_audio / 100.0f); + if (remaining_percent > 1) + remaining_percent = 1; + if (remaining_percent < 0) + remaining_percent = 0; + + music_player->set_volume(ui_music_slider->value() * remaining_percent, 0); // set music + // Set the ambience and other misc. music layers + for (int i = 1; i < music_player->m_channelmax; ++i) { + music_player->set_volume(ui_sfx_slider->value() * remaining_percent, i); + } + sfx_player->set_volume(ui_sfx_slider->value() * remaining_percent); + objection_player->set_volume(ui_sfx_slider->value() * remaining_percent); + blip_player->set_volume(ui_blip_slider->value() * remaining_percent); +} + void Courtroom::set_courtroom_size() { QString filename = "courtroom_design.ini"; @@ -633,7 +664,7 @@ void Courtroom::set_widgets() // If there is a point to it, show all CCCC features. // We also do this this soon so that set_size_and_pos can hide them all later, // if needed. - if (ao_app->cccc_ic_support_enabled) { + if (ao_app->cccc_ic_supported) { ui_pair_button->show(); ui_immediate->show(); ui_showname_enable->show(); @@ -648,7 +679,7 @@ void Courtroom::set_widgets() ui_ic_chat_name->setEnabled(false); } - if (ao_app->casing_alerts_enabled) { + if (ao_app->casing_alerts_supported) { ui_announce_casing->show(); ui_casing->show(); } @@ -1282,11 +1313,6 @@ void Courtroom::done_received() { m_cid = -1; - music_player->set_volume(0); - sfx_player->set_volume(0); - objection_player->set_volume(0); - blip_player->set_volume(0); - if (char_list.size() > 0) { set_char_select(); @@ -1486,7 +1512,7 @@ void Courtroom::update_character(int p_cid) set_iniswap_dropdown(); ui_custom_objection->hide(); - if (ao_app->custom_objection_enabled) // if setting is enabled + if (ao_app->custom_objection_supported) // if setting is enabled { custom_obj_menu->clear(); custom_objections_list.clear(); @@ -1543,11 +1569,7 @@ void Courtroom::update_character(int p_cid) ui_char_select_background->hide(); ui_ic_chat_message->setEnabled(m_cid != -1); ui_ic_chat_message->setFocus(); - // have to call these to make sure music, sfx, and blips don't get accidentally muted forever when we change characters - music_player->set_volume(ui_music_slider->value(), 0); - objection_player->set_volume(ui_sfx_slider->value()); - sfx_player->set_volume(ui_sfx_slider->value()); - blip_player->set_volume(ui_blip_slider->value()); + update_audio_volume(); } void Courtroom::enter_courtroom() @@ -1557,17 +1579,17 @@ void Courtroom::enter_courtroom() set_evidence_page(); - if (ao_app->flipping_enabled) + if (ao_app->flipping_supported) ui_flip->show(); else ui_flip->hide(); - if (ao_app->additive_enabled) + if (ao_app->additive_text_supported) ui_additive->show(); else ui_additive->hide(); - if (ao_app->casing_alerts_enabled) + if (ao_app->casing_alerts_supported) ui_casing->show(); else ui_casing->hide(); @@ -1594,14 +1616,14 @@ void Courtroom::enter_courtroom() break; } - music_player->set_volume(ui_music_slider->value(), 0); // set music - // Set the ambience and other misc. music layers - for (int i = 1; i < music_player->m_channelmax; ++i) { - music_player->set_volume(ui_sfx_slider->value(), i); - } - sfx_player->set_volume(ui_sfx_slider->value()); - objection_player->set_volume(ui_sfx_slider->value()); - blip_player->set_volume(ui_blip_slider->value()); + // Unmute everything + music_player->set_muted(false); + objection_player->set_muted(false); + sfx_player->set_muted(false); + blip_player->set_muted(false); + + // Update the audio sliders + update_audio_volume(); ui_vp_testimony->stop(); // ui_server_chatlog->setHtml(ui_server_chatlog->toHtml()); @@ -1674,7 +1696,7 @@ void Courtroom::list_areas() QString i_area = ""; i_area.append(area_list.at(n_area)); - if (ao_app->arup_enabled) { + if (ao_app->arup_supported) { i_area.append("\n "); i_area.append(arup_statuses.at(n_area)); @@ -1702,7 +1724,7 @@ void Courtroom::list_areas() treeItem->setText(0, area_list.at(n_area)); treeItem->setText(1, i_area); - if (ao_app->arup_enabled) { + if (ao_app->arup_supported) { // Coloring logic here. treeItem->setBackground(1, free_brush); if (arup_locks.at(n_area) == "LOCKED") { @@ -1772,7 +1794,7 @@ void Courtroom::append_server_chatmessage(QString p_name, QString p_message, color = ao_app->get_color("server_chatlog_sender_color", "courtroom_fonts.ini") .name(); - if (!ao_app->auth_packet_enabled && p_message == "Logged in as a moderator.") { + if (!ao_app->auth_packet_supported && p_message == "Logged in as a moderator.") { // Emulate successful authentication on_authentication_state_received(1); } @@ -1842,10 +1864,10 @@ void Courtroom::on_chat_return_pressed() QString f_desk_mod = "chat"; - if (ao_app->desk_mod_enabled) { + if (ao_app->desk_mod_supported) { f_desk_mod = QString::number(ao_app->get_desk_mod(current_char, current_emote)); - if (!ao_app->expanded_desk_mods_enabled) { + if (!ao_app->expanded_desk_mods_supported) { if (f_desk_mod == "2" || f_desk_mod == "4") f_desk_mod = "0"; else if (f_desk_mod == "3" || f_desk_mod == "5") @@ -1889,7 +1911,7 @@ void Courtroom::on_chat_return_pressed() f_emote_mod = PREANIM; } // Turn zoom into preanim zoom - else if (f_emote_mod == ZOOM && ao_app->prezoom_enabled) { + else if (f_emote_mod == ZOOM && ao_app->prezoom_supported) { f_emote_mod = PREANIM_ZOOM; } // Play the sfx @@ -1925,7 +1947,7 @@ void Courtroom::on_chat_return_pressed() QString f_obj_state; - if ((objection_state == 4 && !ao_app->custom_objection_enabled) || + if ((objection_state == 4 && !ao_app->custom_objection_supported) || (objection_state < 0)) f_obj_state = "0"; else if (objection_custom != "" && objection_state == 4) { @@ -1951,7 +1973,7 @@ void Courtroom::on_chat_return_pressed() QString f_flip; - if (ao_app->flipping_enabled) { + if (ao_app->flipping_supported) { if (ui_flip->isChecked()) f_flip = "1"; else @@ -1976,7 +1998,7 @@ void Courtroom::on_chat_return_pressed() packet_contents.append(f_text_color); // If the server we're on supports CCCC stuff, we should use it! - if (ao_app->cccc_ic_support_enabled) { + if (ao_app->cccc_ic_supported) { // If there is a showname entered, use that -- else, just send an empty // packet-part. if (!ui_ic_chat_name->text().isEmpty()) { @@ -1990,7 +2012,7 @@ void Courtroom::on_chat_return_pressed() // ourselves. Or a charid of -1 or lower, through some means. if (other_charid > -1 && other_charid != m_cid) { QString packet = QString::number(other_charid); - if (ao_app->effects_enabled) // Only servers with effects enabled will + if (ao_app->effects_supported) // Only servers with effects enabled will // support pair reordering packet += "^" + QString::number(pair_order); packet_contents.append(packet); @@ -1999,7 +2021,7 @@ void Courtroom::on_chat_return_pressed() packet_contents.append("-1"); } // Send the offset as it's gonna be used regardless - if(ao_app->y_offset_enabled) + if(ao_app->y_offset_supported) packet_contents.append(QString::number(char_offset) + "&" + QString::number(char_vert_offset)); else packet_contents.append(QString::number(char_offset)); @@ -2015,7 +2037,7 @@ void Courtroom::on_chat_return_pressed() // If the server we're on supports Looping SFX and Screenshake, use it if the // emote uses it. - if (ao_app->looping_sfx_support_enabled) { + if (ao_app->looping_sfx_supported) { packet_contents.append( ao_app->get_sfx_looping(current_char, current_emote)); packet_contents.append(QString::number(screenshake_state)); @@ -2046,10 +2068,10 @@ void Courtroom::on_chat_return_pressed() } } - if (ao_app->additive_enabled) { + if (ao_app->additive_text_supported) { packet_contents.append(ui_additive->isChecked() ? "1" : "0"); } - if (ao_app->effects_enabled) { + if (ao_app->effects_supported) { QString fx_sound = ao_app->get_effect_property(effect, current_char, "sound"); QString p_effect = @@ -2195,7 +2217,7 @@ void Courtroom::unpack_chatmessage(QStringList p_contents) // supports CCCC's IC features, or if it's just japing us. Also, don't // forget! A size 15 message will have indices from 0 to 14. if (n_string < p_contents.size() && - (n_string < MS_MINIMUM || ao_app->cccc_ic_support_enabled)) { + (n_string < MS_MINIMUM || ao_app->cccc_ic_supported)) { m_chatmessage[n_string] = p_contents.at(n_string); } else { @@ -2490,7 +2512,7 @@ void Courtroom::display_pair_character(QString other_charid, QString other_offse } } // Flip the pair character - if (ao_app->flipping_enabled && m_chatmessage[OTHER_FLIP].toInt() == 1) + if (ao_app->flipping_supported && m_chatmessage[OTHER_FLIP].toInt() == 1) ui_vp_sideplayer_char->set_flipped(true); else ui_vp_sideplayer_char->set_flipped(false); @@ -2604,33 +2626,38 @@ void Courtroom::do_screenshake() // This way, the animation is reset in such a way that last played 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 wit the chat text being detached from the chat box! + // Works great with the chat text being detached from the chat box! screenshake_animation_group->setCurrentTime( screenshake_animation_group->duration()); screenshake_animation_group->clear(); - QList<QWidget *> affected_list = {ui_vp_background, ui_vp_player_char, + const QList<QWidget *> &affected_list = {ui_vp_background, ui_vp_player_char, ui_vp_sideplayer_char, ui_vp_chatbox}; // I would prefer if this was its own "shake" function to be honest. - foreach (QWidget *ui_element, affected_list) { + for (QWidget *ui_element : affected_list) { QPropertyAnimation *screenshake_animation = new QPropertyAnimation(ui_element, "pos", this); QPoint pos_default = QPoint(ui_element->x(), ui_element->y()); int duration = 300; // How long does the screenshake last int frequency = 20; // How often in ms is there a "jolt" frame - int maxframes = duration / frequency; - int max_x = 7; // Max deviation from origin on x axis - int max_y = 7; // Max deviation from origin on y axis + // Maximum deviation from the origin position. This is 7 pixels for a 256x192 viewport, + // so we scale that value in accordance with the current viewport height so the shake + // is roughly the same intensity regardless of viewport size. Done as a float operation for maximum accuracy. + int max_deviation = 7 * (float(ui_viewport->height()) / 192); + int maxframes = 15; // duration / frequency; screenshake_animation->setDuration(duration); for (int frame = 0; frame < maxframes; frame++) { double fraction = double(frame * frequency) / duration; - int rng = qrand(); // QRandomGenerator::global()->generate(); - int rand_x = max_x - (int(rng) % (max_x * 2)); - int rand_y = max_y - (int(rng + 100) % (max_y * 2)); - screenshake_animation->setKeyValueAt( - fraction, QPoint(pos_default.x() + rand_x, pos_default.y() + rand_y)); +#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) + int rand_x = max_deviation * (2 * (qrand() / (float)RAND_MAX) - 1) + 1; + int rand_y = max_deviation * (2 * (qrand() / (float)RAND_MAX) - 1) + 1; +#else + int rand_x = QRandomGenerator::system()->bounded(-max_deviation, max_deviation); + int rand_y = QRandomGenerator::system()->bounded(-max_deviation, max_deviation); +#endif + screenshake_animation->setKeyValueAt(fraction, QPoint(pos_default.x() + rand_x, pos_default.y() + rand_y)); } screenshake_animation->setEndValue(pos_default); screenshake_animation->setEasingCurve(QEasingCurve::Linear); @@ -2902,7 +2929,7 @@ void Courtroom::display_evidence_image() bool is_left_side = !(side == "def" || side == "hlp" || side == "jud" || side == "jur"); ui_vp_evidence_display->show_evidence(f_evi_id, f_image, is_left_side, - ui_sfx_slider->value()); + sfx_player->get_volume()); } } @@ -4128,7 +4155,7 @@ void Courtroom::on_ooc_return_pressed() //We ignore it when the server is compatible with 2.8 //Using an arbitrary 2.8 feature flag certainly won't cause issues someday. - if (ooc_message.startsWith("/pos") && !ao_app->effects_enabled) { + if (ooc_message.startsWith("/pos") & !ao_app->effects_supported) { if (ooc_message == "/pos jud") { show_judge_controls(true); } @@ -4854,10 +4881,10 @@ void Courtroom::on_music_list_double_clicked(QTreeWidgetItem *p_item, QStringList packet_contents; packet_contents.append(p_song); packet_contents.append(QString::number(m_cid)); - if ((!ui_ic_chat_name->text().isEmpty() && ao_app->cccc_ic_support_enabled) || - ao_app->effects_enabled) + if ((!ui_ic_chat_name->text().isEmpty() && ao_app->cccc_ic_supported) || + ao_app->effects_supported) packet_contents.append(ui_ic_chat_name->text()); - if (ao_app->effects_enabled) + if (ao_app->effects_supported) packet_contents.append(QString::number(music_flags)); ao_app->send_server_packet(new AOPacket("MC", packet_contents), false); } @@ -4969,10 +4996,10 @@ void Courtroom::music_stop(bool no_effects) packet_contents.append( fake_song); // this is our fake song, playing it triggers special code packet_contents.append(QString::number(m_cid)); - if ((!ui_ic_chat_name->text().isEmpty() && ao_app->cccc_ic_support_enabled) || - ao_app->effects_enabled) + if ((!ui_ic_chat_name->text().isEmpty() && ao_app->cccc_ic_supported) || + ao_app->effects_supported) packet_contents.append(ui_ic_chat_name->text()); - if (ao_app->effects_enabled) { + if (ao_app->effects_supported) { if (no_effects) packet_contents.append("0"); else @@ -5144,7 +5171,7 @@ void Courtroom::on_pair_clicked() if (ui_pair_list->isHidden()) { ui_pair_list->show(); ui_pair_offset_spinbox->show(); - if(ao_app->y_offset_enabled) + if(ao_app->y_offset_supported) ui_pair_vert_offset_spinbox->show(); ui_pair_order_dropdown->show(); ui_mute_list->hide(); @@ -5371,8 +5398,8 @@ void Courtroom::on_guilty_clicked() void Courtroom::on_change_character_clicked() { - sfx_player->set_volume(0); - blip_player->set_volume(0); + sfx_player->set_muted(true); + blip_player->set_muted(true); set_char_select(); @@ -5415,7 +5442,7 @@ void Courtroom::on_spectator_clicked() { char_clicked(-1); } void Courtroom::on_call_mod_clicked() { - if (ao_app->modcall_reason_enabled) { + if (ao_app->modcall_reason_supported) { QMessageBox errorBox; QInputDialog input; @@ -5542,7 +5569,7 @@ qint64 Courtroom::pong() void Courtroom::on_casing_clicked() { - if (ao_app->casing_alerts_enabled) { + if (ao_app->casing_alerts_supported) { if (ui_casing->isChecked()) { QStringList f_packet; @@ -5565,7 +5592,7 @@ void Courtroom::on_casing_clicked() void Courtroom::announce_case(QString title, bool def, bool pro, bool jud, bool jur, bool steno) { - if (ao_app->casing_alerts_enabled) { + if (ao_app->casing_alerts_supported) { QStringList f_packet; f_packet.append(title); diff --git a/src/emotes.cpp b/src/emotes.cpp index 669aa17..69d1185 100644 --- a/src/emotes.cpp +++ b/src/emotes.cpp @@ -13,8 +13,15 @@ void Courtroom::initialize_emotes() ui_emote_right->setObjectName("ui_emote_right"); ui_emote_dropdown = new QComboBox(this); + ui_emote_dropdown->setContextMenuPolicy(Qt::CustomContextMenu); ui_emote_dropdown->setObjectName("ui_emote_dropdown"); + emote_menu = new QMenu(this); + emote_menu->setObjectName("ui_emote_menu"); + + emote_preview = new AOEmotePreview(this, ao_app); + emote_preview->setObjectName("ui_emote_preview"); + connect(ui_emote_left, &AOButton::clicked, this, &Courtroom::on_emote_left_clicked); connect(ui_emote_right, &AOButton::clicked, this, @@ -22,6 +29,16 @@ void Courtroom::initialize_emotes() connect(ui_emote_dropdown, QOverload<int>::of(&QComboBox::activated), this, &Courtroom::on_emote_dropdown_changed); + connect(ui_emote_dropdown, + &AOEmoteButton::customContextMenuRequested, this, + &Courtroom::show_emote_menu); + + connect(ui_pre, QOverload<int>::of(&QCheckBox::stateChanged), this, &Courtroom::update_emote_preview); + connect(ui_flip, &AOButton::clicked, this, &Courtroom::update_emote_preview); + connect(ui_pair_offset_spinbox, QOverload<int>::of(&QSpinBox::valueChanged), this, + &Courtroom::update_emote_preview); + connect(ui_pair_vert_offset_spinbox, QOverload<int>::of(&QSpinBox::valueChanged), this, + &Courtroom::update_emote_preview); } void Courtroom::refresh_emotes() @@ -76,9 +93,14 @@ void Courtroom::refresh_emotes() f_emote->set_id(n); + f_emote->setContextMenuPolicy(Qt::CustomContextMenu); connect(f_emote, &AOEmoteButton::emote_clicked, this, &Courtroom::on_emote_clicked); + connect(f_emote, + &AOEmoteButton::customContextMenuRequested, this, + &Courtroom::show_emote_menu); + ++x_mod_count; if (x_mod_count == emote_columns) { @@ -185,15 +207,77 @@ void Courtroom::select_emote(int p_id) } ui_emote_dropdown->setCurrentIndex(current_emote); - + update_emote_preview(); ui_ic_chat_message->setFocus(); } +void Courtroom::update_emote_preview() { + if (!emote_preview->isVisible()) { + return; + } + QString emote; + QString pre = ao_app->get_pre_emote(current_char, current_emote); + if (ui_pre->isChecked() && !pre.isEmpty() && pre != "-") { + emote = pre; + } + else { + emote = "(b)" + ao_app->get_emote(current_char, current_emote); + } + preview_emote(emote); +} + void Courtroom::on_emote_clicked(int p_id) { select_emote(p_id + max_emotes_on_page * current_emote_page); } +void Courtroom::show_emote_menu(const QPoint &pos) +{ + QWidget* button = qobject_cast<QWidget*>(sender()); + int id = current_emote; + if (qobject_cast<AOEmoteButton*>(button)) { + AOEmoteButton* emote_button = qobject_cast<AOEmoteButton*>(sender()); + id = emote_button->get_id(); + } + int emote_num = id + max_emotes_on_page * current_emote_page; + emote_menu->clear(); + emote_menu->setDefaultAction(emote_menu->addAction("Preview Selected", this, [=]{ + emote_preview->show(); + emote_preview->raise(); + emote_preview->set_widgets(); + update_emote_preview(); + } + )); + QString prefix = ""; + QString f_pre = ao_app->get_pre_emote(current_char, emote_num); + if (!f_pre.isEmpty() && f_pre != "-") { + emote_menu->addAction("Preview pre: " + f_pre, this, [=]{ preview_emote(f_pre); }); + } + + QString f_emote = ao_app->get_emote(current_char, emote_num); + if (!f_emote.isEmpty()) { + emote_menu->addAction("Preview idle: " + f_emote, this, [=]{ preview_emote("(a)" + f_emote); }); + emote_menu->addAction("Preview talk: " + f_emote, this, [=]{ preview_emote("(b)" + f_emote); }); + QStringList c_paths = { + ao_app->get_image_suffix(ao_app->get_character_path(current_char, "(c)" + f_emote)), + ao_app->get_image_suffix(ao_app->get_character_path(current_char, "(c)/" + f_emote)) + }; + // if there is a (c) animation + if (file_exists(ui_vp_player_char->find_image(c_paths))) { + emote_menu->addAction("Preview segway: " + f_emote, this, [=]{ preview_emote("(c)" + f_emote); }); + } + } + emote_menu->popup(button->mapToGlobal(pos)); +} + +void Courtroom::preview_emote(QString f_emote) +{ + emote_preview->show(); + emote_preview->raise(); + emote_preview->set_widgets(); + emote_preview->play(f_emote, current_char, ui_flip->isChecked(), ui_pair_offset_spinbox->value(), ui_pair_vert_offset_spinbox->value()); +} + void Courtroom::on_emote_left_clicked() { --current_emote_page; diff --git a/src/hardware_functions.cpp b/src/hardware_functions.cpp index 4bd2399..233318e 100644 --- a/src/hardware_functions.cpp +++ b/src/hardware_functions.cpp @@ -38,6 +38,16 @@ QString get_hdid() CloseHandle(hToken); return returnHDID; } +#elif defined(ANDROID) +QString get_hdid() +{ + QAndroidJniObject appctx = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;").callObjectMethod("getApplicationContext","()Landroid/content/Context;"); + QAndroidJniObject androidId = QAndroidJniObject::callStaticObjectMethod("android/provider/Settings$Secure","getString", + "(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;", + appctx.callObjectMethod("getContentResolver", "()Landroid/content/ContentResolver;").object<jobject>(), + QAndroidJniObject::fromString("android_id").object<jstring>()); + return androidId.toString(); +} #elif QT_VERSION < QT_VERSION_CHECK(5, 11, 0) #if (defined(LINUX) || defined(__linux__)) diff --git a/src/packet_distribution.cpp b/src/packet_distribution.cpp index e032613..0fc5eee 100644 --- a/src/packet_distribution.cpp +++ b/src/packet_distribution.cpp @@ -39,20 +39,20 @@ void AOApplication::server_packet_received(AOPacket *p_packet) goto end; // default(legacy) values - yellow_text_enabled = false; - prezoom_enabled = false; - flipping_enabled = false; - custom_objection_enabled = false; - desk_mod_enabled = false; - evidence_enabled = false; - cccc_ic_support_enabled = false; - arup_enabled = false; - casing_alerts_enabled = false; - modcall_reason_enabled = false; - looping_sfx_support_enabled = false; - additive_enabled = false; - effects_enabled = false; - y_offset_enabled = false; + yellow_text_supported = false; + prezoom_supported = false; + flipping_supported = false; + custom_objection_supported = false; + desk_mod_supported = false; + evidence_supported = false; + cccc_ic_supported = false; + arup_supported = false; + casing_alerts_supported = false; + modcall_reason_supported = false; + looping_sfx_supported = false; + additive_text_supported = false; + effects_supported = false; + y_offset_supported = false; QString f_hdid; f_hdid = get_hdid(); @@ -88,53 +88,53 @@ void AOApplication::server_packet_received(AOPacket *p_packet) } } else if (header == "FL") { - yellow_text_enabled = false; - prezoom_enabled = false; - flipping_enabled = false; - custom_objection_enabled = false; - desk_mod_enabled = false; - evidence_enabled = false; - cccc_ic_support_enabled = false; - arup_enabled = false; - casing_alerts_enabled = false; - modcall_reason_enabled = false; - looping_sfx_support_enabled = false; - additive_enabled = false; - effects_enabled = false; - expanded_desk_mods_enabled = false; - auth_packet_enabled = false; + yellow_text_supported = false; + prezoom_supported = false; + flipping_supported = false; + custom_objection_supported = false; + desk_mod_supported = false; + evidence_supported = false; + cccc_ic_supported = false; + arup_supported = false; + casing_alerts_supported = false; + modcall_reason_supported = false; + looping_sfx_supported = false; + additive_text_supported = false; + effects_supported = false; + expanded_desk_mods_supported = false; + auth_packet_supported = false; if (f_packet.contains("yellowtext", Qt::CaseInsensitive)) - yellow_text_enabled = true; + yellow_text_supported = true; if (f_packet.contains("prezoom", Qt::CaseInsensitive)) - prezoom_enabled = true; + prezoom_supported = true; if (f_packet.contains("flipping", Qt::CaseInsensitive)) - flipping_enabled = true; + flipping_supported = true; if (f_packet.contains("customobjections", Qt::CaseInsensitive)) - custom_objection_enabled = true; + custom_objection_supported = true; if (f_packet.contains("deskmod", Qt::CaseInsensitive)) - desk_mod_enabled = true; + desk_mod_supported = true; if (f_packet.contains("evidence", Qt::CaseInsensitive)) - evidence_enabled = true; + evidence_supported = true; if (f_packet.contains("cccc_ic_support", Qt::CaseInsensitive)) - cccc_ic_support_enabled = true; + cccc_ic_supported = true; if (f_packet.contains("arup", Qt::CaseInsensitive)) - arup_enabled = true; + arup_supported = true; if (f_packet.contains("casing_alerts", Qt::CaseInsensitive)) - casing_alerts_enabled = true; + casing_alerts_supported = true; if (f_packet.contains("modcall_reason", Qt::CaseInsensitive)) - modcall_reason_enabled = true; + modcall_reason_supported = true; if (f_packet.contains("looping_sfx", Qt::CaseInsensitive)) - looping_sfx_support_enabled = true; + looping_sfx_supported = true; if (f_packet.contains("additive", Qt::CaseInsensitive)) - additive_enabled = true; + additive_text_supported = true; if (f_packet.contains("effects", Qt::CaseInsensitive)) - effects_enabled = true; + effects_supported = true; if (f_packet.contains("y_offset", Qt::CaseInsensitive)) - y_offset_enabled = true; + y_offset_supported = true; if (f_packet.contains("expanded_desk_mods", Qt::CaseInsensitive)) - expanded_desk_mods_enabled = true; + expanded_desk_mods_supported = true; if (f_packet.contains("auth_packet", Qt::CaseInsensitive)) - auth_packet_enabled = true; + auth_packet_supported = true; } else if (header == "PN") { if (f_contents.size() < 2) @@ -603,7 +603,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet) } // Auth packet else if (header == "AUTH") { - if (!courtroom_constructed || !auth_packet_enabled || f_contents.size() < 1) + if (!courtroom_constructed || !auth_packet_supported || f_contents.size() < 1) goto end; bool ok; int authenticated = f_contents.at(0).toInt(&ok); diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp index be162b2..dc95dc3 100644 --- a/src/text_file_functions.cpp +++ b/src/text_file_functions.cpp @@ -40,6 +40,12 @@ int AOApplication::get_default_blip() return result; } +int AOApplication::get_default_suppress_audio() +{ + int result = configini->value("suppress_audio", 50).toInt(); + return result; +} + int AOApplication::get_max_log_size() { int result = configini->value("log_maximum", 200).toInt(); |
