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:
parent
f16d099274
commit
fa47841440
22 changed files with 165 additions and 46 deletions
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ target_link_libraries(novus-gamelauncher
|
|||
PRIVATE
|
||||
Novus::Common
|
||||
Physis::Physis
|
||||
Physis::Logger
|
||||
KF6::I18n
|
||||
Qt6::Core
|
||||
Qt6::Widgets)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
19
apps/mapeditor/include/appstate.h
Normal file
19
apps/mapeditor/include/appstate.h
Normal 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();
|
||||
};
|
|
@ -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;
|
||||
};
|
||||
|
|
26
apps/mapeditor/include/objectlistwidget.h
Normal file
26
apps/mapeditor/include/objectlistwidget.h
Normal 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;
|
||||
};
|
9
apps/mapeditor/src/appstate.cpp
Normal file
9
apps/mapeditor/src/appstate.cpp
Normal 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)
|
||||
{
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
72
apps/mapeditor/src/objectlistwidget.cpp
Normal file
72
apps/mapeditor/src/objectlistwidget.cpp
Normal 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"
|
|
@ -19,7 +19,6 @@ target_link_libraries(novus-mateditor
|
|||
Novus::MdlPart
|
||||
Novus::MtrlPart
|
||||
Physis::Physis
|
||||
Physis::Logger
|
||||
KF6::I18n
|
||||
Qt6::Core
|
||||
Qt6::Widgets)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
7
extern/CMakeLists.txt
vendored
7
extern/CMakeLists.txt
vendored
|
@ -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
2
extern/libphysis
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 31b72594f565ce8d87e0f951692691579c738b41
|
||||
Subproject commit bf8aa831d0c57e40d724602bfd5c311cf1422390
|
Loading…
Add table
Reference in a new issue