diff --git a/apps/armoury/CMakeLists.txt b/apps/armoury/CMakeLists.txt index 5fcfbf6..a6bb589 100644 --- a/apps/armoury/CMakeLists.txt +++ b/apps/armoury/CMakeLists.txt @@ -41,7 +41,6 @@ target_link_libraries(novus-armoury Novus::SklbPart Novus::MtrlPart Physis::Physis - Physis::Logger imgui Qt6::Core Qt6::Widgets @@ -68,4 +67,4 @@ if (WIN32) else() install(FILES zone.xiv.armoury.desktop DESTINATION ${KDE_INSTALL_APPDIR}) install(FILES zone.xiv.armoury.svg DESTINATION ${KDE_INSTALL_FULL_ICONDIR}/hicolor/scalable/apps) -endif() \ No newline at end of file +endif() diff --git a/apps/armoury/src/main.cpp b/apps/armoury/src/main.cpp index 6aaad0e..eb1677e 100644 --- a/apps/armoury/src/main.cpp +++ b/apps/armoury/src/main.cpp @@ -7,7 +7,6 @@ #include "aboutdata.h" #include "mainwindow.h" -#include "physis_logger.h" #include "settings.h" int main(int argc, char *argv[]) @@ -23,12 +22,10 @@ int main(int argc, char *argv[]) qputenv("QT_MESSAGE_PATTERN", "[%{time yyyy-MM-dd h:mm:ss.zzz}] %{if-category}[%{category}] %{endif}[%{type}] %{message}"); } - setup_physis_logging(); - const QString gameDir{getGameDirectory()}; const std::string gameDirStd{gameDir.toStdString()}; MainWindow w(physis_gamedata_initialize(gameDirStd.c_str())); w.show(); return QApplication::exec(); -} \ No newline at end of file +} diff --git a/apps/gamelauncher/CMakeLists.txt b/apps/gamelauncher/CMakeLists.txt index d98eb7e..e8036db 100644 --- a/apps/gamelauncher/CMakeLists.txt +++ b/apps/gamelauncher/CMakeLists.txt @@ -15,7 +15,6 @@ target_link_libraries(novus-gamelauncher PRIVATE Novus::Common Physis::Physis - Physis::Logger KF6::I18n Qt6::Core Qt6::Widgets) diff --git a/apps/gamelauncher/src/main.cpp b/apps/gamelauncher/src/main.cpp index 54032b5..529a2e6 100644 --- a/apps/gamelauncher/src/main.cpp +++ b/apps/gamelauncher/src/main.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include "aboutdata.h" #include "mainwindow.h" @@ -26,10 +25,8 @@ int main(int argc, char *argv[]) qputenv("QT_MESSAGE_PATTERN", "[%{time yyyy-MM-dd h:mm:ss.zzz}] %{if-category}[%{category}] %{endif}[%{type}] %{message}"); } - setup_physis_logging(); - MainWindow w; w.show(); return app.exec(); -} \ No newline at end of file +} diff --git a/apps/karuku/CMakeLists.txt b/apps/karuku/CMakeLists.txt index d9e864a..baf12c5 100644 --- a/apps/karuku/CMakeLists.txt +++ b/apps/karuku/CMakeLists.txt @@ -19,7 +19,6 @@ target_link_libraries(novus-karuku Novus::Common Novus::ExdPart Physis::Physis - Physis::Logger Qt6::Core Qt6::Widgets Qt6::Network) @@ -44,4 +43,4 @@ if (WIN32) else() install(FILES zone.xiv.karaku.desktop DESTINATION ${KDE_INSTALL_APPDIR}) install(FILES zone.xiv.karaku.svg DESTINATION ${KDE_INSTALL_FULL_ICONDIR}/hicolor/scalable/apps) -endif() \ No newline at end of file +endif() diff --git a/apps/karuku/src/main.cpp b/apps/karuku/src/main.cpp index c77de9c..9088949 100644 --- a/apps/karuku/src/main.cpp +++ b/apps/karuku/src/main.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include "aboutdata.h" #include "mainwindow.h" @@ -23,12 +22,10 @@ int main(int argc, char *argv[]) qputenv("QT_MESSAGE_PATTERN", "[%{time yyyy-MM-dd h:mm:ss.zzz}] %{if-category}[%{category}] %{endif}[%{type}] %{message}"); } - setup_physis_logging(); - const QString gameDir{getGameDirectory()}; const std::string gameDirStd{gameDir.toStdString()}; MainWindow w(physis_gamedata_initialize(gameDirStd.c_str())); w.show(); return app.exec(); -} \ No newline at end of file +} diff --git a/apps/mapeditor/CMakeLists.txt b/apps/mapeditor/CMakeLists.txt index 6cd997e..086c689 100644 --- a/apps/mapeditor/CMakeLists.txt +++ b/apps/mapeditor/CMakeLists.txt @@ -8,12 +8,16 @@ target_sources(novus-mapeditor include/maplistwidget.h include/mapview.h include/objectpass.h + include/objectlistwidget.h + include/appstate.h src/main.cpp src/mainwindow.cpp src/maplistwidget.cpp src/mapview.cpp - src/objectpass.cpp) + src/objectpass.cpp + src/objectlistwidget.cpp + src/appstate.cpp) target_include_directories(novus-mapeditor PUBLIC include) @@ -22,7 +26,6 @@ target_link_libraries(novus-mapeditor Novus::Common Novus::MdlPart Physis::Physis - Physis::Logger Qt6::Core Qt6::Widgets) diff --git a/apps/mapeditor/include/appstate.h b/apps/mapeditor/include/appstate.h new file mode 100644 index 0000000..09273b3 --- /dev/null +++ b/apps/mapeditor/include/appstate.h @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2025 Joshua Goins +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +#include + +class AppState : public QObject +{ + Q_OBJECT + +public: + explicit AppState(QObject *parent = nullptr); + + physis_LayerGroup bgGroup; + +Q_SIGNALS: + void mapLoaded(); +}; diff --git a/apps/mapeditor/include/mainwindow.h b/apps/mapeditor/include/mainwindow.h index f1373a9..a6021b5 100644 --- a/apps/mapeditor/include/mainwindow.h +++ b/apps/mapeditor/include/mainwindow.h @@ -7,8 +7,10 @@ #include "filecache.h" +class ObjectListWidget; struct GameData; class MapView; +class AppState; class MainWindow : public KXmlGuiWindow { @@ -24,4 +26,6 @@ private: GameData *data = nullptr; FileCache cache; MapView *mapView = nullptr; + ObjectListWidget *objectListWidget = nullptr; + AppState *m_appState = nullptr; }; diff --git a/apps/mapeditor/include/objectlistwidget.h b/apps/mapeditor/include/objectlistwidget.h new file mode 100644 index 0000000..30401ec --- /dev/null +++ b/apps/mapeditor/include/objectlistwidget.h @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: 2025 Joshua Goins +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include +#include +#include + +class QStringListModel; +class AppState; + +class ObjectListWidget : public QWidget +{ + Q_OBJECT + +public: + explicit ObjectListWidget(AppState *appState, QWidget *parent = nullptr); + +private: + void refresh(); + + QListView *listWidget = nullptr; + AppState *m_appState; + QStringListModel *m_originalModel; +}; diff --git a/apps/mapeditor/src/appstate.cpp b/apps/mapeditor/src/appstate.cpp new file mode 100644 index 0000000..0314580 --- /dev/null +++ b/apps/mapeditor/src/appstate.cpp @@ -0,0 +1,9 @@ +// SPDX-FileCopyrightText: 2025 Joshua Goins +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "appstate.h" + +AppState::AppState(QObject *parent) + : QObject(parent) +{ +} diff --git a/apps/mapeditor/src/main.cpp b/apps/mapeditor/src/main.cpp index 92f2f72..911832c 100644 --- a/apps/mapeditor/src/main.cpp +++ b/apps/mapeditor/src/main.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include "aboutdata.h" #include "mainwindow.h" @@ -23,12 +22,10 @@ int main(int argc, char *argv[]) qputenv("QT_MESSAGE_PATTERN", "[%{time yyyy-MM-dd h:mm:ss.zzz}] %{if-category}[%{category}] %{endif}[%{type}] %{message}"); } - setup_physis_logging(); - const QString gameDir{getGameDirectory()}; const std::string gameDirStd{gameDir.toStdString()}; MainWindow w(physis_gamedata_initialize(gameDirStd.c_str())); w.show(); return app.exec(); -} \ No newline at end of file +} diff --git a/apps/mapeditor/src/mainwindow.cpp b/apps/mapeditor/src/mainwindow.cpp index f4fd934..d7a1957 100644 --- a/apps/mapeditor/src/mainwindow.cpp +++ b/apps/mapeditor/src/mainwindow.cpp @@ -12,8 +12,10 @@ #include #include +#include "appstate.h" #include "maplistwidget.h" #include "mapview.h" +#include "objectlistwidget.h" MainWindow::MainWindow(GameData *data) : KXmlGuiWindow() @@ -22,10 +24,16 @@ MainWindow::MainWindow(GameData *data) { setMinimumSize(1280, 720); + m_appState = new AppState(this); + auto dummyWidget = new QSplitter(); dummyWidget->setChildrenCollapsible(false); setCentralWidget(dummyWidget); + objectListWidget = new ObjectListWidget(m_appState); + objectListWidget->setMaximumWidth(400); + dummyWidget->addWidget(objectListWidget); + mapView = new MapView(data, cache); dummyWidget->addWidget(mapView); @@ -76,6 +84,14 @@ void MainWindow::openMap(const QString &basePath) mapView->addTerrain(bgPath, tera); setWindowTitle(basePath); + + QString lgbPath = QStringLiteral("bg/%1/level/bg.lgb").arg(base2Path); + std::string bgLgbPathStd = lgbPath.toStdString(); + + auto bg_buffer = physis_gamedata_extract_file(data, bgLgbPathStd.c_str()); + m_appState->bgGroup = physis_layergroup_read(bg_buffer); + + Q_EMIT m_appState->mapLoaded(); } #include "moc_mainwindow.cpp" diff --git a/apps/mapeditor/src/objectlistwidget.cpp b/apps/mapeditor/src/objectlistwidget.cpp new file mode 100644 index 0000000..4a12d97 --- /dev/null +++ b/apps/mapeditor/src/objectlistwidget.cpp @@ -0,0 +1,72 @@ +// SPDX-FileCopyrightText: 2025 Joshua Goins +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "objectlistwidget.h" + +#include +#include +#include +#include +#include + +#include "appstate.h" + +ObjectListWidget::ObjectListWidget(AppState *appState, QWidget *parent) + : QWidget(parent) + , m_appState(appState) +{ + auto layout = new QVBoxLayout(); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + setLayout(layout); + + auto searchModel = new QSortFilterProxyModel(); + searchModel->setRecursiveFilteringEnabled(true); + searchModel->setFilterCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive); + + auto searchEdit = new QLineEdit(); + searchEdit->setWhatsThis(i18nc("@info:whatsthis", "Search box for Excel sheet names.")); + searchEdit->setPlaceholderText(i18nc("@info:placeholder", "Search…")); + searchEdit->setClearButtonEnabled(true); + searchEdit->setProperty("_breeze_borders_sides", QVariant::fromValue(QFlags{Qt::BottomEdge})); + connect(searchEdit, &QLineEdit::textChanged, this, [=](const QString &text) { + searchModel->setFilterRegularExpression(text); + }); + layout->addWidget(searchEdit); + + m_originalModel = new QStringListModel(); + searchModel->setSourceModel(m_originalModel); + + listWidget = new QListView(); + listWidget->setWhatsThis(i18nc("@info:whatsthis", "A list of Excel sheet names. Select one to view it's contents.")); + listWidget->setModel(searchModel); + + layout->addWidget(listWidget); + + connect(m_appState, &AppState::mapLoaded, this, &ObjectListWidget::refresh); +} + +void ObjectListWidget::refresh() +{ + QStringList list; + + for (int i = 0; i < m_appState->bgGroup.num_chunks; i++) { + const auto chunk = m_appState->bgGroup.chunks[i]; + for (int j = 0; j < chunk.num_layers; j++) { + const auto layer = chunk.layers[j]; + for (int z = 0; z < layer.num_objects; z++) { + const auto object = layer.objects[z]; + const QString name = QString::fromLatin1(object.name); + if (true) { // TODO: do display names if we have them + list << i18n("Unknown (%1)", object.instance_id); + } else { + list << name; + } + } + } + } + + m_originalModel->setStringList(list); +} + +#include "moc_objectlistwidget.cpp" diff --git a/apps/mateditor/CMakeLists.txt b/apps/mateditor/CMakeLists.txt index 31d9c0a..52ea87d 100644 --- a/apps/mateditor/CMakeLists.txt +++ b/apps/mateditor/CMakeLists.txt @@ -19,7 +19,6 @@ target_link_libraries(novus-mateditor Novus::MdlPart Novus::MtrlPart Physis::Physis - Physis::Logger KF6::I18n Qt6::Core Qt6::Widgets) diff --git a/apps/mateditor/src/main.cpp b/apps/mateditor/src/main.cpp index 9f719bb..87b2ba3 100644 --- a/apps/mateditor/src/main.cpp +++ b/apps/mateditor/src/main.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include "aboutdata.h" #include "mainwindow.h" @@ -26,12 +25,10 @@ int main(int argc, char *argv[]) qputenv("QT_MESSAGE_PATTERN", "[%{time yyyy-MM-dd h:mm:ss.zzz}] %{if-category}[%{category}] %{endif}[%{type}] %{message}"); } - setup_physis_logging(); - const QString gameDir{getGameDirectory()}; const std::string gameDirStd{gameDir.toStdString()}; MainWindow w(physis_gamedata_initialize(gameDirStd.c_str())); w.show(); return app.exec(); -} \ No newline at end of file +} diff --git a/apps/mdlviewer/CMakeLists.txt b/apps/mdlviewer/CMakeLists.txt index 7195b37..809c5e8 100644 --- a/apps/mdlviewer/CMakeLists.txt +++ b/apps/mdlviewer/CMakeLists.txt @@ -16,7 +16,6 @@ target_link_libraries(novus-mdlviewer Novus::MdlPart Novus::Common Physis::Physis - Physis::Logger KF6::XmlGui Qt6::Core Qt6::Widgets) @@ -41,4 +40,4 @@ if (WIN32) else() install(FILES zone.xiv.mdlviewer.desktop DESTINATION ${KDE_INSTALL_APPDIR}) install(FILES zone.xiv.mdlviewer.svg DESTINATION ${KDE_INSTALL_FULL_ICONDIR}/hicolor/scalable/apps) -endif() \ No newline at end of file +endif() diff --git a/apps/mdlviewer/src/main.cpp b/apps/mdlviewer/src/main.cpp index dd1aef2..0426bbd 100644 --- a/apps/mdlviewer/src/main.cpp +++ b/apps/mdlviewer/src/main.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include "aboutdata.h" #include "mainwindow.h" @@ -23,12 +22,10 @@ int main(int argc, char *argv[]) qputenv("QT_MESSAGE_PATTERN", "[%{time yyyy-MM-dd h:mm:ss.zzz}] %{if-category}[%{category}] %{endif}[%{type}] %{message}"); } - setup_physis_logging(); - const QString gameDir{getGameDirectory()}; const std::string gameDirStd{gameDir.toStdString()}; MainWindow w(physis_gamedata_initialize(gameDirStd.c_str())); w.show(); return app.exec(); -} \ No newline at end of file +} diff --git a/apps/sagasu/CMakeLists.txt b/apps/sagasu/CMakeLists.txt index a88b25d..1bfe277 100644 --- a/apps/sagasu/CMakeLists.txt +++ b/apps/sagasu/CMakeLists.txt @@ -46,7 +46,6 @@ target_link_libraries(novus-sagasu Novus::DicPart Novus::MtrlPart Novus::LuabPart - Physis::Logger Qt6::Concurrent Qt6::Network) @@ -70,4 +69,4 @@ if (WIN32) else() install(FILES zone.xiv.sagasu.desktop DESTINATION ${KDE_INSTALL_APPDIR}) install(FILES zone.xiv.sagasu.svg DESTINATION ${KDE_INSTALL_FULL_ICONDIR}/hicolor/scalable/apps) -endif() \ No newline at end of file +endif() diff --git a/apps/sagasu/src/main.cpp b/apps/sagasu/src/main.cpp index 7793866..9107a6e 100644 --- a/apps/sagasu/src/main.cpp +++ b/apps/sagasu/src/main.cpp @@ -5,7 +5,6 @@ #include #include -#include #include "aboutdata.h" #include "mainwindow.h" @@ -27,12 +26,10 @@ int main(int argc, char *argv[]) qputenv("QT_MESSAGE_PATTERN", "[%{time yyyy-MM-dd h:mm:ss.zzz}] %{if-category}[%{category}] %{endif}[%{type}] %{message}"); } - setup_physis_logging(); - const QString gameDir{getGameDirectory()}; const std::string gameDirStd{gameDir.toStdString()}; MainWindow w(gameDir, physis_gamedata_initialize(gameDirStd.c_str())); w.show(); return app.exec(); -} \ No newline at end of file +} diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index c16c24b..59be721 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -11,13 +11,10 @@ FetchContent_Declare( ) FetchContent_MakeAvailable(Corrosion) -corrosion_import_crate(MANIFEST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/libphysis/Cargo.toml FEATURES logging) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libphysis/logger) - +corrosion_import_crate(MANIFEST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/libphysis/Cargo.toml) target_include_directories(physis INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/libphysis/target/public) add_library(Physis::Physis ALIAS physis) -add_library(Physis::Logger ALIAS physis-logger) add_subdirectory(magic_enum EXCLUDE_FROM_ALL) add_subdirectory(tinygltf EXCLUDE_FROM_ALL) @@ -27,4 +24,4 @@ add_subdirectory(dxbc EXCLUDE_FROM_ALL) # For some reason, FFXIV uses a *32-bit* Lua compiler. We have to build it as 32-bit or else loading the bytecode fails. add_compile_options(-m32) add_link_options(-m32) -add_subdirectory(luadec51 EXCLUDE_FROM_ALL) \ No newline at end of file +add_subdirectory(luadec51 EXCLUDE_FROM_ALL) diff --git a/extern/libphysis b/extern/libphysis index 31b7259..bf8aa83 160000 --- a/extern/libphysis +++ b/extern/libphysis @@ -1 +1 @@ -Subproject commit 31b72594f565ce8d87e0f951692691579c738b41 +Subproject commit bf8aa831d0c57e40d724602bfd5c311cf1422390