diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e3a364..e46a314 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 3.10 FATAL_ERROR) # because of c++17 project(amuse) +if(POLICY CMP0072) + cmake_policy(SET CMP0072 NEW) +endif() + if (NOT MSVC) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -81,9 +85,15 @@ target_include_directories(amuse PUBLIC include) target_link_libraries(amuse PUBLIC athena-core lzokay + logvisor + fmt ${ZLIB_LIBRARIES} ) +target_atdna(amuse atdna_AudioGroupPool.cpp include/amuse/AudioGroupPool.hpp) +target_atdna(amuse atdna_AudioGroupProject.cpp include/amuse/AudioGroupProject.hpp) +target_atdna(amuse atdna_AudioGroupSampleDirectory.cpp include/amuse/AudioGroupSampleDirectory.hpp) + if(NX) target_sources(amuse PRIVATE include/switch_math.hpp) endif() @@ -157,11 +167,11 @@ if(TARGET boo AND NOT WINDOWS_STORE AND NOT NX) endif() # Editor - find_package(Qt5 COMPONENTS Widgets) - if (Qt5Widgets_FOUND) - message(STATUS "Qt5 found, amuse-gui will be built") + find_package(Qt6 COMPONENTS Widgets PATHS /usr/local/opt/qt) + if (Qt6Widgets_FOUND) + message(STATUS "Qt6 found, amuse-gui will be built") add_subdirectory(Editor) else() - message(STATUS "Qt5 not found, amuse-gui will not be built") + message(STATUS "Qt6 not found, amuse-gui will not be built") endif() endif() diff --git a/Editor/ADSREditor.cpp b/Editor/ADSREditor.cpp index 928267f..a903b04 100644 --- a/Editor/ADSREditor.cpp +++ b/Editor/ADSREditor.cpp @@ -153,9 +153,9 @@ void ADSRView::mousePressEvent(QMouseEvent* ev) { QPointF((width() - 30.0) * ((adTime + 1.0) / totalTime) + 30.0, sustainY), }; const qreal dists[] = { - PointDistance(ev->localPos(), points[0]), - PointDistance(ev->localPos(), points[1]), - PointDistance(ev->localPos(), points[2]), + PointDistance(ev->position(), points[0]), + PointDistance(ev->position(), points[1]), + PointDistance(ev->position(), points[2]), }; int minDist = 0; @@ -196,16 +196,16 @@ void ADSRView::mouseMoveEvent(QMouseEvent* ev) { qreal totalTime = adTime + 1.0 + relTime; if (m_dragPoint == 0) { - const qreal newAttack = std::max(0.0, (ev->localPos().x() - 30.0) / (width() - 30.0) * totalTime); + const qreal newAttack = std::max(0.0, (ev->position().x() - 30.0) / (width() - 30.0) * totalTime); const qreal delta = newAttack - aTime; ctrls->setAttackAndDecay(newAttack, std::max(0.0, ctrls->m_decay->value() - delta), m_cycleIdx); } else if (m_dragPoint == 1) { - const qreal newDecay = std::max(0.0, (ev->localPos().x() - 30.0) * totalTime / (width() - 30.0) - aTime); - const qreal newSustain = (-ev->localPos().y() + (height() - 16.0)) / (height() - 16.0); + const qreal newDecay = std::max(0.0, (ev->position().x() - 30.0) * totalTime / (width() - 30.0) - aTime); + const qreal newSustain = (-ev->position().y() + (height() - 16.0)) / (height() - 16.0); ctrls->setDecayAndSustain(newDecay, newSustain * 100.0, m_cycleIdx); } else if (m_dragPoint == 2) { const qreal newRelease = - std::max(0.0, (width() - 30.0) * (adTime + 1.0) / (ev->localPos().x() - 30.0) - (adTime + 1.0)); + std::max(0.0, (width() - 30.0) * (adTime + 1.0) / (ev->position().x() - 30.0) - (adTime + 1.0)); ctrls->setRelease(newRelease, m_cycleIdx); ctrls->m_release->setValue(newRelease); } diff --git a/Editor/CMakeLists.txt b/Editor/CMakeLists.txt index e13a8f1..d6b4660 100644 --- a/Editor/CMakeLists.txt +++ b/Editor/CMakeLists.txt @@ -7,13 +7,13 @@ set(CMAKE_AUTOUIC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) -find_package(Qt5 COMPONENTS LinguistTools Network Qml Svg Widgets Xml REQUIRED) +find_package(Qt6 COMPONENTS LinguistTools Network Qml SvgWidgets Widgets Xml REQUIRED) configure_file(resources/translation_res.qrc translation_res.qrc @ONLY) set(TRANSLATIONS resources/lang_de.ts ) -QT5_CREATE_TRANSLATION(QM_FILES ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../lib ${TRANSLATIONS}) +QT6_CREATE_TRANSLATION(QM_FILES ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../lib ${TRANSLATIONS}) add_executable(amuse-gui WIN32 MACOSX_BUNDLE ADSREditor.cpp @@ -137,11 +137,11 @@ set_target_properties(amuse-gui PROPERTIES target_link_libraries(amuse-gui ${PLAT_LIBS} - Qt5::Network - Qt5::Qml - Qt5::Svg - Qt5::Widgets - Qt5::Xml + Qt6::Network + Qt6::Qml + Qt6::SvgWidgets + Qt6::Widgets + Qt6::Xml amuse athena-core diff --git a/Editor/Common.cpp b/Editor/Common.cpp index 440d644..d3f6808 100644 --- a/Editor/Common.cpp +++ b/Editor/Common.cpp @@ -73,8 +73,8 @@ void ShowInGraphicalShell(QWidget* parent, const QString& pathIn) { // we cannot select a file here, because no file browser really supports it... const QString folder = fileInfo.isDir() ? fileInfo.absoluteFilePath() : fileInfo.filePath(); QProcess browserProc; - const QString browserArgs = QStringLiteral("xdg-open \"%1\"").arg(QFileInfo(folder).path()); - browserProc.startDetached(browserArgs); + const QStringList browserArgs = QStringList() << QStringLiteral("%1").arg(QFileInfo(folder).path()); + browserProc.startDetached(QStringLiteral("xdg-open"), browserArgs); #endif } diff --git a/Editor/CurveEditor.cpp b/Editor/CurveEditor.cpp index 0203cc0..98e3ad1 100644 --- a/Editor/CurveEditor.cpp +++ b/Editor/CurveEditor.cpp @@ -137,11 +137,11 @@ void CurveView::mouseMoveEvent(QMouseEvent* ev) { } const qreal xIncrement = (width() - 30.0) / 127.0; - const int idx = int(std::round((ev->localPos().x() - 30.0) / xIncrement)); + const int idx = int(std::round((ev->position().x() - 30.0) / xIncrement)); if (idx < 0 || idx > 127) { return; } - const int val = 127 - std::clamp(0, int(std::round(ev->localPos().y() / (height() - 16.0) * 127.0)), 127); + const int val = 127 - std::clamp(0, int(std::round(ev->position().y() / (height() - 16.0) * 127.0)), 127); CurveEditUndoCommand::RedoData newData; auto& curve = static_cast(table); diff --git a/Editor/EditorWidget.cpp b/Editor/EditorWidget.cpp index e6ef335..00e5752 100644 --- a/Editor/EditorWidget.cpp +++ b/Editor/EditorWidget.cpp @@ -226,7 +226,7 @@ AddRemoveButtons::AddRemoveButtons(QWidget* parent) static QIcon ListingDeleteIcon; static QIcon ListingDeleteHoveredIcon; -void ListingDeleteButton::enterEvent(QEvent* event) { setIcon(ListingDeleteHoveredIcon); } +void ListingDeleteButton::enterEvent(QEnterEvent* event) { setIcon(ListingDeleteHoveredIcon); } void ListingDeleteButton::leaveEvent(QEvent* event) { setIcon(ListingDeleteIcon); } @@ -264,7 +264,7 @@ bool BaseObjectDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, c connect(findUsagesAction, &QAction::triggered, this, &BaseObjectDelegate::doFindUsages); menu->addAction(findUsagesAction); - menu->popup(ev->globalPos()); + menu->popup(ev->globalPosition().toPoint()); } } return false; diff --git a/Editor/EditorWidget.hpp b/Editor/EditorWidget.hpp index 0841e92..e734085 100644 --- a/Editor/EditorWidget.hpp +++ b/Editor/EditorWidget.hpp @@ -229,7 +229,7 @@ class ListingDeleteButton : public QPushButton { Q_OBJECT public: explicit ListingDeleteButton(QWidget* parent = Q_NULLPTR); - void enterEvent(QEvent* event) override; + void enterEvent(QEnterEvent* event) override; void leaveEvent(QEvent* event) override; }; diff --git a/Editor/KeyboardWidget.cpp b/Editor/KeyboardWidget.cpp index 41ec70e..9876ff2 100644 --- a/Editor/KeyboardWidget.cpp +++ b/Editor/KeyboardWidget.cpp @@ -39,7 +39,7 @@ KeyboardOctave::KeyboardOctave(int octave, const QString& svgPath, QWidget* pare const auto& naturalKeyName = NaturalKeyNames[i]; if (renderer()->elementExists(naturalKeyName)) { - m_natural[i] = renderer()->matrixForElement(naturalKeyName).mapRect(renderer()->boundsOnElement(naturalKeyName)); + m_natural[i] = renderer()->transformForElement(naturalKeyName).mapRect(renderer()->boundsOnElement(naturalKeyName)); } } @@ -47,7 +47,7 @@ KeyboardOctave::KeyboardOctave(int octave, const QString& svgPath, QWidget* pare const auto& sharpKeyName = SharpKeyNames[i]; if (renderer()->elementExists(sharpKeyName)) { - m_sharp[i] = renderer()->matrixForElement(sharpKeyName).mapRect(renderer()->boundsOnElement(sharpKeyName)); + m_sharp[i] = renderer()->transformForElement(sharpKeyName).mapRect(renderer()->boundsOnElement(sharpKeyName)); } } @@ -151,7 +151,7 @@ void KeyboardWidget::mouseReleaseEvent(QMouseEvent* event) { m_holding = false; } -void KeyboardWidget::enterEvent(QEvent* event) { +void KeyboardWidget::enterEvent(QEnterEvent* event) { if (m_statusFocus) m_statusFocus->enter(); } @@ -179,7 +179,7 @@ KeyboardSlider::KeyboardSlider(QWidget* parent) : QSlider(parent) {} KeyboardSlider::~KeyboardSlider() = default; -void KeyboardSlider::enterEvent(QEvent* event) { +void KeyboardSlider::enterEvent(QEnterEvent* event) { if (m_statusFocus) m_statusFocus->enter(); } diff --git a/Editor/KeyboardWidget.hpp b/Editor/KeyboardWidget.hpp index fc3ad66..7f41c42 100644 --- a/Editor/KeyboardWidget.hpp +++ b/Editor/KeyboardWidget.hpp @@ -54,7 +54,7 @@ public: void mouseMoveEvent(QMouseEvent* event) override; void mousePressEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; - void enterEvent(QEvent* event) override; + void enterEvent(QEnterEvent* event) override; void leaveEvent(QEvent* event) override; void wheelEvent(QWheelEvent* event) override; void showEvent(QShowEvent* event) override; @@ -74,7 +74,7 @@ public: explicit KeyboardSlider(QWidget* parent = Q_NULLPTR); ~KeyboardSlider() override; - void enterEvent(QEvent* event) override; + void enterEvent(QEnterEvent* event) override; void leaveEvent(QEvent* event) override; void setStatusFocus(StatusBarFocus* statusFocus); void sliderChange(SliderChange change) override; diff --git a/Editor/KeymapEditor.cpp b/Editor/KeymapEditor.cpp index 274a189..7dacd6c 100644 --- a/Editor/KeymapEditor.cpp +++ b/Editor/KeymapEditor.cpp @@ -138,7 +138,7 @@ int KeymapView::getKey(const QPoint& localPos) const { } void KeymapView::mouseMoveEvent(QMouseEvent* ev) { - const int octave = ev->x() / 280; + const int octave = ev->position().x() / 280; const int key = getKey(ev->pos() - QPoint(octave * 280, height() / 2 - 100)); if (octave >= 0 && key >= 0) { @@ -174,7 +174,7 @@ KeymapView::KeymapView(QWidget* parent) if (m_octaveRenderer.elementExists(naturalKeyName)) { m_natural[i] = - m_octaveRenderer.matrixForElement(naturalKeyName).mapRect(m_octaveRenderer.boundsOnElement(naturalKeyName)); + m_octaveRenderer.transformForElement(naturalKeyName).mapRect(m_octaveRenderer.boundsOnElement(naturalKeyName)); } } @@ -183,7 +183,7 @@ KeymapView::KeymapView(QWidget* parent) if (m_octaveRenderer.elementExists(sharpKeyName)) { m_sharp[i] = - m_octaveRenderer.matrixForElement(sharpKeyName).mapRect(m_octaveRenderer.boundsOnElement(sharpKeyName)); + m_octaveRenderer.transformForElement(sharpKeyName).mapRect(m_octaveRenderer.boundsOnElement(sharpKeyName)); } } diff --git a/Editor/LayersEditor.cpp b/Editor/LayersEditor.cpp index 5209e64..4a41f24 100644 --- a/Editor/LayersEditor.cpp +++ b/Editor/LayersEditor.cpp @@ -519,7 +519,7 @@ void LayersTableView::deleteSelection() { std::vector> data; data.reserve(list.size()); - for (const QModelIndex idx : list) { + for (const QModelIndex& idx : list) { data.emplace_back(amuse::LayerMapping{}, idx.row()); } diff --git a/Editor/MainWindow.cpp b/Editor/MainWindow.cpp index 492f7bc..4809fb8 100644 --- a/Editor/MainWindow.cpp +++ b/Editor/MainWindow.cpp @@ -29,6 +29,8 @@ #include #include +#include + MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) , m_navIt(m_navList.begin()) @@ -261,7 +263,7 @@ void MainWindow::updateWindowTitle() { void MainWindow::updateRecentFileActions() { const QSettings settings; const QStringList files = settings.value(QStringLiteral("recentFileList")).toStringList(); - const int numRecentFiles = std::min(files.size(), int(MaxRecentFiles)); + const int numRecentFiles = std::min(files.size(), qsizetype(MaxRecentFiles)); for (int i = 0; i < numRecentFiles; ++i) { const QString text = QStringLiteral("&%1 %2").arg(i + 1).arg(QDir(files[i]).dirName()); @@ -519,8 +521,9 @@ bool MainWindow::_setEditor(EditorWidget* editor, bool appendNav) { m_interactiveSeq.reset(); if (editor != m_ui.editorContents->currentWidget() && m_ui.editorContents->currentWidget() != m_faceSvg) getEditorWidget()->unloadData(); - if (appendNav && m_navIt != m_navList.end()) - m_navList.erase(m_navIt + 1, m_navList.end()); + if (appendNav && m_navIt != m_navList.end()) { + m_navList.erase(std::next(m_navIt, 1), m_navList.end()); + } if (!editor || !editor->valid()) { m_ui.editorContents->setCurrentWidget(m_faceSvg); updateWindowTitle(); @@ -1189,7 +1192,7 @@ bool TreeDelegate::editorEvent(QEvent* event, QAbstractItemModel* __model, const connect(renameAction, &QAction::triggered, this, &TreeDelegate::doRename); menu->addAction(renameAction); - menu->popup(ev->globalPos()); + menu->popup(ev->globalPosition().toPoint()); } } @@ -1484,12 +1487,12 @@ void MainWindow::newLayersAction() { } void MainWindow::updateNavigationButtons() { - m_goForward->setDisabled(m_navIt == m_navList.end() || m_navIt + 1 == m_navList.end()); + m_goForward->setDisabled(m_navIt == m_navList.end() || std::next(m_navIt, 1) == m_navList.end()); m_goBack->setDisabled(m_navIt == m_navList.begin()); } void MainWindow::goForward() { - if (m_navIt == m_navList.end() || m_navIt + 1 == m_navList.end()) + if (m_navIt == m_navList.end() || std::next(m_navIt, 1) == m_navList.end()) return; ++m_navIt; openEditor(*m_navIt, false); diff --git a/Editor/MainWindow.hpp b/Editor/MainWindow.hpp index 24c2ffb..9e6e95e 100644 --- a/Editor/MainWindow.hpp +++ b/Editor/MainWindow.hpp @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -113,8 +112,8 @@ class MainWindow : public QMainWindow { Ui::MainWindow m_ui; QAction* m_goBack; QAction* m_goForward; - QLinkedList m_navList; - QLinkedList::iterator m_navIt; + std::list m_navList; + std::list::iterator m_navIt; QAction* m_clearRecentFileAct; QAction* m_recentFileActs[MaxRecentFiles]; TreeDelegate m_treeDelegate; diff --git a/Editor/ProjectModel.cpp b/Editor/ProjectModel.cpp index b9f2ffe..d79bff4 100644 --- a/Editor/ProjectModel.cpp +++ b/Editor/ProjectModel.cpp @@ -22,7 +22,7 @@ QIcon ProjectModel::SongGroupNode::Icon; QIcon ProjectModel::SoundGroupNode::Icon; OutlineFilterProxyModel::OutlineFilterProxyModel(ProjectModel* source) -: QSortFilterProxyModel(source), m_usageKey({}, Qt::CaseInsensitive) { +: QSortFilterProxyModel(source), m_usageKey({}, QRegularExpression::CaseInsensitiveOption) { setSourceModel(source); setRecursiveFilteringEnabled(true); setFilterCaseSensitivity(Qt::CaseInsensitive); @@ -31,10 +31,10 @@ OutlineFilterProxyModel::OutlineFilterProxyModel(ProjectModel* source) void OutlineFilterProxyModel::setFilterRegExp(const QString& pattern) { if (pattern.startsWith(QStringLiteral("usages:"))) { m_usageKey.setPattern(pattern.mid(7)); - QSortFilterProxyModel::setFilterRegExp(QString()); + QSortFilterProxyModel::setFilterRegularExpression(QString()); } else { m_usageKey.setPattern(QString()); - QSortFilterProxyModel::setFilterRegExp(pattern); + QSortFilterProxyModel::setFilterRegularExpression(pattern); } } @@ -498,8 +498,12 @@ ProjectModel::BasePoolObjectNode* ProjectModel::CollectionNode::nodeOfId(amuse:: } ProjectModel::ProjectModel(const QString& path, QObject* parent) -: QAbstractItemModel(parent), m_dir(path), m_outlineProxy(this), m_nullProxy(this), m_pageObjectProxy(this) { - m_root = amuse::MakeObj(); +: QAbstractItemModel(parent) +, m_dir(path) +, m_root(amuse::MakeObj()) +, m_outlineProxy(this) +, m_nullProxy(this) +, m_pageObjectProxy(this) { GroupNode::Icon = QIcon(QStringLiteral(":/icons/IconGroup.svg")); SongGroupNode::Icon = QIcon(QStringLiteral(":/icons/IconSongGroup.svg")); diff --git a/Editor/ProjectModel.hpp b/Editor/ProjectModel.hpp index 5443806..0d86395 100644 --- a/Editor/ProjectModel.hpp +++ b/Editor/ProjectModel.hpp @@ -38,7 +38,7 @@ enum AmuseItemEditFlags { class OutlineFilterProxyModel : public QSortFilterProxyModel { Q_OBJECT - QRegExp m_usageKey; + QRegularExpression m_usageKey; public: explicit OutlineFilterProxyModel(ProjectModel* source); @@ -91,10 +91,6 @@ public: private: QDir m_dir; - OutlineFilterProxyModel m_outlineProxy; - NullItemProxyModel m_nullProxy; - PageObjectProxyModel m_pageObjectProxy; - amuse::ProjectDatabase m_projectDatabase; std::unordered_map> m_groups; @@ -380,6 +376,11 @@ public: QString MakeDedupedSubprojectName(const QString& origName); static QString MakeDedupedName(const QString& origName, amuse::NameDB* db); +private: + OutlineFilterProxyModel m_outlineProxy; + NullItemProxyModel m_nullProxy; + PageObjectProxyModel m_pageObjectProxy; + public: explicit ProjectModel(const QString& path, QObject* parent = Q_NULLPTR); ~ProjectModel() override; diff --git a/Editor/SongGroupEditor.cpp b/Editor/SongGroupEditor.cpp index 001a94b..9111ed7 100644 --- a/Editor/SongGroupEditor.cpp +++ b/Editor/SongGroupEditor.cpp @@ -390,7 +390,7 @@ bool MIDIFileDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, con connect(sngAction, &QAction::triggered, this, &MIDIFileDelegate::doExportSNG); menu->addAction(sngAction); - menu->popup(ev->globalPos()); + menu->popup(ev->globalPosition().toPoint()); } } return false; @@ -1172,7 +1172,7 @@ void PageTableView::deleteSelection() { std::vector> data; data.reserve(list.size()); - for (const QModelIndex idx : list) { + for (const QModelIndex& idx : list) { data.emplace_back(model()->data(idx).toInt() - 1, amuse::SongGroupIndex::PageEntry{}); } diff --git a/Editor/SoundMacroEditor.cpp b/Editor/SoundMacroEditor.cpp index f963df2..64ab342 100644 --- a/Editor/SoundMacroEditor.cpp +++ b/Editor/SoundMacroEditor.cpp @@ -243,7 +243,7 @@ CommandWidget::CommandWidget(QWidget* parent, amuse::SoundMacro::ICmd* cmd, amus cb->setFixedHeight(30); cb->setProperty("fieldIndex", f); cb->setProperty("fieldName", fieldName); - for (const auto choice : field.m_choices) { + for (const auto& choice : field.m_choices) { if (choice.empty()) { break; } @@ -514,7 +514,10 @@ void SoundMacroListing::startAutoscroll(QWidget* source, QMouseEvent* event, int m_autoscrollTimer = startTimer(50); m_autoscrollDelta = delta; m_autoscrollSource = source; - m_autoscrollEvent = *event; + if (m_autoscrollEvent) { + delete m_autoscrollEvent; + } + m_autoscrollEvent = event->clone(); } void SoundMacroListing::stopAutoscroll() { @@ -523,6 +526,9 @@ void SoundMacroListing::stopAutoscroll() { m_autoscrollTimer = -1; } m_autoscrollDelta = 0; + if (m_autoscrollEvent) { + delete m_autoscrollEvent; + } m_autoscrollSource = nullptr; } @@ -534,7 +540,7 @@ void SoundMacroListing::timerEvent(QTimerEvent* event) { int valueDelta = bar->value() - oldValue; if (valueDelta != 0) { if (m_autoscrollSource) - QApplication::sendEvent(m_autoscrollSource, &m_autoscrollEvent); + QApplication::sendEvent(m_autoscrollSource, m_autoscrollEvent); update(); } } @@ -811,7 +817,7 @@ CatalogueItem::CatalogueItem(amuse::SoundMacro::CmdOp op, const QString& name, c CatalogueItem::CatalogueItem(const CatalogueItem& other, QWidget* parent) : QWidget(parent), m_op(other.getCmdOp()) { QHBoxLayout* layout = new QHBoxLayout; QHBoxLayout* oldLayout = static_cast(other.layout()); - m_iconLab.setPixmap(*static_cast(oldLayout->itemAt(0)->widget())->pixmap()); + m_iconLab.setPixmap(static_cast(oldLayout->itemAt(0)->widget())->pixmap(Qt::ReturnByValue)); layout->addWidget(&m_iconLab); m_label.setText(static_cast(oldLayout->itemAt(1)->widget())->text()); layout->addWidget(&m_label); diff --git a/Editor/SoundMacroEditor.hpp b/Editor/SoundMacroEditor.hpp index 49415ef..7006e34 100644 --- a/Editor/SoundMacroEditor.hpp +++ b/Editor/SoundMacroEditor.hpp @@ -115,7 +115,7 @@ class SoundMacroListing : public QWidget { int m_autoscrollTimer = -1; int m_autoscrollDelta = 0; QWidget* m_autoscrollSource = nullptr; - QMouseEvent m_autoscrollEvent = {{}, {}, {}, {}, {}}; + QMouseEvent* m_autoscrollEvent = nullptr; void startAutoscroll(QWidget* source, QMouseEvent* event, int delta); void stopAutoscroll(); bool beginDrag(CommandWidget* widget); diff --git a/Editor/StudioSetupWidget.cpp b/Editor/StudioSetupWidget.cpp index 6640bfa..d616e65 100644 --- a/Editor/StudioSetupWidget.cpp +++ b/Editor/StudioSetupWidget.cpp @@ -496,7 +496,10 @@ void EffectListing::startAutoscroll(QWidget* source, QMouseEvent* event, int del m_autoscrollTimer = startTimer(50); m_autoscrollDelta = delta; m_autoscrollSource = source; - m_autoscrollEvent = *event; + if (m_autoscrollEvent != nullptr) { + delete m_autoscrollEvent; + } + m_autoscrollEvent = event->clone(); } void EffectListing::stopAutoscroll() { @@ -505,6 +508,9 @@ void EffectListing::stopAutoscroll() { m_autoscrollTimer = -1; } m_autoscrollDelta = 0; + if (m_autoscrollEvent != nullptr) { + delete m_autoscrollEvent; + } m_autoscrollSource = nullptr; } @@ -516,7 +522,7 @@ void EffectListing::timerEvent(QTimerEvent* event) { int valueDelta = bar->value() - oldValue; if (valueDelta != 0) { if (m_autoscrollSource) - QApplication::sendEvent(m_autoscrollSource, &m_autoscrollEvent); + QApplication::sendEvent(m_autoscrollSource, m_autoscrollEvent); update(); } } @@ -740,7 +746,7 @@ EffectCatalogueItem::EffectCatalogueItem(const EffectCatalogueItem& other, QWidg : QWidget(parent), m_type(other.getType()) { QHBoxLayout* layout = new QHBoxLayout; QHBoxLayout* oldLayout = static_cast(other.layout()); - m_iconLab.setPixmap(*static_cast(oldLayout->itemAt(0)->widget())->pixmap()); + m_iconLab.setPixmap(static_cast(oldLayout->itemAt(0)->widget())->pixmap(Qt::ReturnByValue)); layout->addWidget(&m_iconLab); m_label.setText(static_cast(oldLayout->itemAt(1)->widget())->text()); layout->addWidget(&m_label); diff --git a/Editor/StudioSetupWidget.hpp b/Editor/StudioSetupWidget.hpp index 758a0c4..fceaf1a 100644 --- a/Editor/StudioSetupWidget.hpp +++ b/Editor/StudioSetupWidget.hpp @@ -126,7 +126,7 @@ class EffectListing : public QWidget { int m_autoscrollTimer = -1; int m_autoscrollDelta = 0; QWidget* m_autoscrollSource = nullptr; - QMouseEvent m_autoscrollEvent = {{}, {}, {}, {}, {}}; + QMouseEvent* m_autoscrollEvent = nullptr; void startAutoscroll(QWidget* source, QMouseEvent* event, int delta); void stopAutoscroll(); bool beginDrag(EffectWidget* widget); diff --git a/Editor/main.cpp b/Editor/main.cpp index b111a9e..1e6da72 100644 --- a/Editor/main.cpp +++ b/Editor/main.cpp @@ -56,7 +56,7 @@ MainWindow* g_MainWindow = nullptr; int main(int argc, char* argv[]) { QApplication::setAttribute(Qt::AA_Use96Dpi); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) +#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif diff --git a/Editor/platforms/freedesktop/CMakeLists.txt b/Editor/platforms/freedesktop/CMakeLists.txt index 5bb5674..0e3983f 100644 --- a/Editor/platforms/freedesktop/CMakeLists.txt +++ b/Editor/platforms/freedesktop/CMakeLists.txt @@ -1,6 +1,6 @@ -include_directories(${LIBPNG_INCLUDE_DIR}) add_executable(amuse-mkqticon mkqticon.c) -target_link_libraries(amuse-mkqticon ${PNG_LIB} ${ZLIB_LIBRARIES}) +target_link_libraries(amuse-mkqticon ${PNG_LIBRARIES} ${ZLIB_LIBRARIES}) +target_include_directories(amuse-mkqticon PRIVATE ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR}) macro(declare_qticon_target) add_custom_command(OUTPUT ${amuse_BINARY_DIR}/Editor/platforms/freedesktop/mainicon_qt.bin diff --git a/Editor/resources/lang_de.ts b/Editor/resources/lang_de.ts index 2e3087c..5f877fc 100644 --- a/Editor/resources/lang_de.ts +++ b/Editor/resources/lang_de.ts @@ -676,344 +676,344 @@ - + Go Back - + Go Forward - + Clear Recent Projects - + Amuse[*] - + %1/%2/%3[*] - Amuse - + %1[*] - Amuse - - + + The directory at '%1' must not be empty. - - + + Directory empty - + The directory at '%1' must exist for the Amuse editor. - + Directory does not exist - + __amuse_test__ - + The directory at '%1' must be writable for the Amuse editor: %2 - + Unable to write to directory - + No Audio Devices Found - + Virtual MIDI-In - + No MIDI Devices Found - + SUSTAIN - - + + Unsaved Changes - + Save Changes in %1? - + New Project - + The directory at '%1' does not exist. - + Bad Directory - + Opening - - - - - + + + + + Scanning Project - + Opening %1 - + Open Project - + Discard Changes in %1? - + Reloading Samples - + Scanning %1 - + Import Project - + The file at '%1' could not be interpreted as a MusyX container. - + Unsupported MusyX Container - + Sample Import Mode - + Amuse can import samples as WAV files for ease of editing, import original compressed data for lossless repacking, or both. Exporting the project will prefer whichever version was modified most recently. - + Import Compressed - + Import WAVs - + Import Both - + Raw Import Mode - + Would you like to scan for all MusyX group files in this directory? - + Project Name - + What should this project be named? - - + + Importing - - + + Importing %1 - + Import Songs - + Exporting - + Exporting %1 - - + + Import C Headers - + <p>Importing names from C headers depends on up-to-date, consistent names relative to the sound group data.</p><p>Headers are imported on a per-subproject basis from a single directory. Headers must be named with the form <code>&lt;subproject&gt;.h</code>.</p><p>Group, Song and SFX definitions are matched according to the following forms:<pre>#define GRP&lt;name&gt; &lt;id&gt; #define SNG&lt;name&gt; &lt;id&gt; #define SFX&lt;name> &lt;id&gt;</pre></p><p><strong>This operation cannot be undone! It is recommended to make a backup of the project directory before proceeding.</strong></p><p>Continue?</p> - + Export C Headers - + New Subproject - + What should this subproject be named? - + New SFX Group - + What should the new SFX group in %1 be named? - + New Song Group - + What should the new Song group in %1 be named? - + New ADSR - + What should the new ADSR in %1 be named? - + New Curve - + What should the new Curve in %1 be named? - + New Keymap - + What should the new Keymap in %1 be named? - + New Layers - + What should the new Layers in %1 be named? - + About Amuse - + Export Complete - + %1? @@ -1231,341 +1231,341 @@ ProjectModel - - - - - - + + + + + + Export Error - - - + + + Unable to find group %1 - + Unable to export %1.proj - + Unable to export %1.pool - + Unable to export %1.sdir - + Unable to export %1.samp - + Import Error - + Export Header Error - + Unable to open %1 for reading - + File Exists - + %1 already exists. Overwrite? - + Sound Macros - + ADSRs - + Curves - + Keymaps - + Layers - + Samples - + Naming Conflict - + %1 already exists in this context - + Rename %1 - + Subproject Conflict - + The subproject %1 is already defined - - - + + + Add Subproject %1 - + Sound Group Conflict - - + + The group %1 is already defined - - - + + + Add Sound Group %1 - + Song Group Conflict - - - + + + Add Song Group %1 - + Sound Macro Conflict - + The macro %1 is already defined - - + + Add Sound Macro %1 - + ADSR Conflict - + The ADSR %1 is already defined - - - + + + Add ADSR %1 - + Curve Conflict - + The Curve %1 is already defined - - - + + + Add Curve %1 - + Keymap Conflict - + The Keymap %1 is already defined - - - + + + Add Keymap %1 - + Layers Conflict - + Layers %1 is already defined - - - + + + Add Layers %1 - - + + -copy - + Add SoundMacro %1 - + Cut SongGroup %1 - + Cut SFXGroup %1 - + Cut SoundMacro %1 - + Cut ADSR %1 - + Cut Curve %1 - + Cut Keymap %1 - + Cut Layers %1 - + Delete Subproject - + <p>The subproject %1 will be permanently deleted from the project. Sample files will be permanently removed from the file system.</p><p><strong>This action cannot be undone!</strong></p><p>Continue?</p> - + Delete SongGroup %1 - + Delete SFXGroup %1 - + Delete SoundMacro %1 - + Delete ADSR %1 - + Delete Curve %1 - + Delete Keymap %1 - + Delete Layers %1 - + Delete Sample - + <p>The sample %1 will be permanently deleted from the file system. <p><strong>This action cannot be undone!</strong></p><p>Continue?</p> @@ -1573,7 +1573,7 @@ QDialogButtonBox - + OK @@ -1581,12 +1581,12 @@ QMessageBox - + <h3>About Amuse</h3> - + <p>Amuse is an alternate editor and runtime library for MusyX sound groups.</p><p>MusyX originally served as a widely-deployed audio system for developing games on the Nintendo 64, GameCube, and GameBoy Advance.</p><p>Amuse is available under the MIT license.<br>Please see <a href="https://gitlab.axiodl.com/AxioDL/amuse/blob/master/LICENSE">https://gitlab.axiodl.com/AxioDL/amuse/blob/master/LICENSE</a> for futher information.</p><p>Copyright (C) 2015-2018 Antidote / Jackoalan.</p><p>MusyX is a trademark of Factor 5, LLC.</p><p>Nintendo 64, GameCube, and GameBoy Advance are trademarks of Nintendo Co., Ltd.</p> @@ -1893,72 +1893,72 @@ SoundMacroCatalogue - + Control - + Pitch - + Sample - + Setup - + Special - + Structure - + Volume - + Commands to control the voice - + Commands to control the voice's pitch - + Commands to control the voice's sample playback - + Commands to setup the voice's mixing process - + Miscellaneous commands - + Commands to control macro branching - + Commands to control the voice's volume @@ -1974,17 +1974,17 @@ SoundMacroListing - + Reorder %1 - + Insert %1 - + Delete %1 @@ -2015,17 +2015,17 @@ StudioSetupWidget - + Studio Setup - + Aux A - + Aux B @@ -2041,52 +2041,52 @@ TreeDelegate - + Export GameCube Group - + Find Usages - + Cut - + Copy - + Paste - + Duplicate - + Delete - + Rename - + Exporting - + Exporting %1 diff --git a/include/amuse/Voice.hpp b/include/amuse/Voice.hpp index f3b035e..13211fc 100644 --- a/include/amuse/Voice.hpp +++ b/include/amuse/Voice.hpp @@ -15,6 +15,13 @@ #include "amuse/Studio.hpp" namespace amuse { +constexpr float convertMusyXPanToAmusePan(uint32_t pan) { + // Amuse expects pan values to be between [-1,1] while MusyX expects pan to be between [0,127], we need to make sure + // to map the values properly, we do this by subtracting the center value and then dividing, thus forcing [0, 127] into + // [-1,1], we must also make sure clamp the result so we don't over or underflow. + return std::clamp(static_cast(pan - 64) / 63.f, -1.f, 1.f); +} + class IBackendVoice; struct Keymap; struct LayerMapping; diff --git a/lib/AudioGroupProject.cpp b/lib/AudioGroupProject.cpp index 958b8a3..3cb2116 100644 --- a/lib/AudioGroupProject.cpp +++ b/lib/AudioGroupProject.cpp @@ -57,8 +57,11 @@ static void ReadRangedObjectIds(NameDB* db, athena::io::IStreamReader& r, NameDB template static void WriteRangedObjectIds(athena::io::IStreamWriter& w, const T& list) { - if (list.cbegin() == list.cend()) + if (list.cbegin() == list.cend()) { + uint16_t term = 0xffff; + athena::io::Write::Do({}, term, w); return; + } bool inRange = false; uint16_t lastId = list.cbegin()->first.id & 0x3fff; for (auto it = list.cbegin() + 1; it != list.cend(); ++it) { diff --git a/lib/Emitter.cpp b/lib/Emitter.cpp index a07fff8..34292fa 100644 --- a/lib/Emitter.cpp +++ b/lib/Emitter.cpp @@ -105,8 +105,16 @@ void Emitter::_update() { void Emitter::setVectors(const float* pos, const float* dir) { for (size_t i = 0; i < m_pos.size(); ++i) { - m_pos[i] = pos[i]; - m_dir[i] = dir[i]; + if (!std::isnan(pos[i])) { + m_pos[i] = pos[i]; + } else { + m_pos[i] = 0.f; + } + if (!std::isnan(dir[i])) { + m_dir[i] = dir[i]; + } else { + m_dir[i] = 0.f; + } } m_dirty = true; } diff --git a/lib/Listener.cpp b/lib/Listener.cpp index c948837..7ecb8b2 100644 --- a/lib/Listener.cpp +++ b/lib/Listener.cpp @@ -12,10 +12,26 @@ static constexpr Vector3f Cross(const Vector3f& a, const Vector3f& b) { void Listener::setVectors(const float* pos, const float* dir, const float* heading, const float* up) { for (int i = 0; i < 3; ++i) { - m_pos[i] = pos[i]; - m_dir[i] = dir[i]; - m_heading[i] = heading[i]; - m_up[i] = up[i]; + if (!std::isnan(pos[i])) { + m_pos[i] = pos[i]; + } else { + m_pos[i] = 0.f; + } + if (!std::isnan(dir[i])) { + m_dir[i] = dir[i]; + } else { + m_dir[i] = 0.f; + } + if (!std::isnan(heading[i])) { + m_heading[i] = heading[i]; + } else { + m_heading[i] = 0.f; + } + if (std::isnan(up[i])) { + m_up[i] = up[i]; + } else { + m_heading[i] = 0.f; + } } m_heading = Normalize(m_heading);