1
Fork 0
mirror of https://github.com/redstrate/Novus.git synced 2025-05-14 20:47:46 +00:00

Add object list to map editor, begin parsing background LGB

This is super basic at the moment, but still super cool!
This commit is contained in:
Joshua Goins 2025-05-13 15:50:26 -04:00
parent f16d099274
commit fa47841440
22 changed files with 165 additions and 46 deletions

View file

@ -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()
endif()

View file

@ -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();
}
}

View file

@ -15,7 +15,6 @@ target_link_libraries(novus-gamelauncher
PRIVATE
Novus::Common
Physis::Physis
Physis::Logger
KF6::I18n
Qt6::Core
Qt6::Widgets)

View file

@ -4,7 +4,6 @@
#include <KLocalizedString>
#include <QApplication>
#include <physis.hpp>
#include <physis_logger.h>
#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();
}
}

View file

@ -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()
endif()

View file

@ -4,7 +4,6 @@
#include <KLocalizedString>
#include <QApplication>
#include <physis.hpp>
#include <physis_logger.h>
#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();
}
}

View file

@ -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)

View file

@ -0,0 +1,19 @@
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later
#include <QObject>
#include <physis.hpp>
class AppState : public QObject
{
Q_OBJECT
public:
explicit AppState(QObject *parent = nullptr);
physis_LayerGroup bgGroup;
Q_SIGNALS:
void mapLoaded();
};

View file

@ -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;
};

View file

@ -0,0 +1,26 @@
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <QListView>
#include <QWidget>
#include <physis.hpp>
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;
};

View file

@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later
#include "appstate.h"
AppState::AppState(QObject *parent)
: QObject(parent)
{
}

View file

@ -4,7 +4,6 @@
#include <KLocalizedString>
#include <QApplication>
#include <physis.hpp>
#include <physis_logger.h>
#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();
}
}

View file

@ -12,8 +12,10 @@
#include <QSplitter>
#include <physis.hpp>
#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"

View file

@ -0,0 +1,72 @@
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later
#include "objectlistwidget.h"
#include <KLocalizedString>
#include <QLineEdit>
#include <QSortFilterProxyModel>
#include <QStringListModel>
#include <QVBoxLayout>
#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"

View file

@ -19,7 +19,6 @@ target_link_libraries(novus-mateditor
Novus::MdlPart
Novus::MtrlPart
Physis::Physis
Physis::Logger
KF6::I18n
Qt6::Core
Qt6::Widgets)

View file

@ -4,7 +4,6 @@
#include <KLocalizedString>
#include <QApplication>
#include <physis.hpp>
#include <physis_logger.h>
#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();
}
}

View file

@ -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()
endif()

View file

@ -4,7 +4,6 @@
#include <KLocalizedString>
#include <QApplication>
#include <physis.hpp>
#include <physis_logger.h>
#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();
}
}

View file

@ -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()
endif()

View file

@ -5,7 +5,6 @@
#include <KLocalizedString>
#include <physis.hpp>
#include <physis_logger.h>
#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();
}
}

View file

@ -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)
add_subdirectory(luadec51 EXCLUDE_FROM_ALL)

2
extern/libphysis vendored

@ -1 +1 @@
Subproject commit 31b72594f565ce8d87e0f951692691579c738b41
Subproject commit bf8aa831d0c57e40d724602bfd5c311cf1422390