--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qmlfrontend/engine_instance.cpp Wed Jul 31 23:14:27 2019 +0200
@@ -0,0 +1,134 @@
+#include "engine_instance.h"
+
+#include <QDebug>
+#include <QLibrary>
+#include <QOpenGLFunctions>
+#include <QSurface>
+
+static QOpenGLContext* currentOpenglContext = nullptr;
+extern "C" void (*getProcAddress(const char* fn))() {
+ if (!currentOpenglContext)
+ return nullptr;
+ else
+ return currentOpenglContext->getProcAddress(fn);
+}
+
+EngineInstance::EngineInstance(const QString& libraryPath, QObject* parent)
+ : QObject(parent) {
+ QLibrary hwlib(libraryPath);
+
+ if (!hwlib.load())
+ qWarning() << "Engine library not found" << hwlib.errorString();
+
+ hedgewars_engine_protocol_version =
+ reinterpret_cast<Engine::hedgewars_engine_protocol_version_t*>(
+ hwlib.resolve("hedgewars_engine_protocol_version"));
+ start_engine =
+ reinterpret_cast<Engine::start_engine_t*>(hwlib.resolve("start_engine"));
+ generate_preview = reinterpret_cast<Engine::generate_preview_t*>(
+ hwlib.resolve("generate_preview"));
+ dispose_preview = reinterpret_cast<Engine::dispose_preview_t*>(
+ hwlib.resolve("dispose_preview"));
+ cleanup = reinterpret_cast<Engine::cleanup_t*>(hwlib.resolve("cleanup"));
+
+ send_ipc = reinterpret_cast<Engine::send_ipc_t*>(hwlib.resolve("send_ipc"));
+ read_ipc = reinterpret_cast<Engine::read_ipc_t*>(hwlib.resolve("read_ipc"));
+
+ setup_current_gl_context =
+ reinterpret_cast<Engine::setup_current_gl_context_t*>(
+ hwlib.resolve("setup_current_gl_context"));
+ render_frame =
+ reinterpret_cast<Engine::render_frame_t*>(hwlib.resolve("render_frame"));
+ advance_simulation = reinterpret_cast<Engine::advance_simulation_t*>(
+ hwlib.resolve("advance_simulation"));
+ move_camera =
+ reinterpret_cast<Engine::move_camera_t*>(hwlib.resolve("move_camera"));
+ simple_event =
+ reinterpret_cast<Engine::simple_event_t*>(hwlib.resolve("simple_event"));
+ long_event =
+ reinterpret_cast<Engine::long_event_t*>(hwlib.resolve("long_event"));
+ positioned_event = reinterpret_cast<Engine::positioned_event_t*>(
+ hwlib.resolve("positioned_event"));
+
+ m_isValid = hedgewars_engine_protocol_version && start_engine &&
+ generate_preview && dispose_preview && cleanup && send_ipc &&
+ read_ipc && setup_current_gl_context && render_frame &&
+ advance_simulation && move_camera && simple_event && long_event &&
+ positioned_event;
+
+ emit isValidChanged(m_isValid);
+
+ if (isValid()) {
+ qDebug() << "Loaded engine library with protocol version"
+ << hedgewars_engine_protocol_version();
+
+ m_instance = start_engine();
+ } else {
+ qDebug("Engine library load failed");
+ }
+}
+
+EngineInstance::~EngineInstance() {
+ if (m_isValid) cleanup(m_instance);
+}
+
+void EngineInstance::sendConfig(const GameConfig& config) {
+ for (auto b : config.config()) {
+ send_ipc(m_instance, reinterpret_cast<uint8_t*>(b.data()),
+ static_cast<size_t>(b.size()));
+ }
+}
+
+void EngineInstance::advance(quint32 ticks) {
+ advance_simulation(m_instance, ticks);
+}
+
+void EngineInstance::moveCamera(const QPoint& delta) {
+ move_camera(m_instance, delta.x(), delta.y());
+}
+
+void EngineInstance::simpleEvent(Engine::SimpleEventType event_type) {
+ simple_event(m_instance, event_type);
+}
+
+void EngineInstance::longEvent(Engine::LongEventType event_type,
+ Engine::LongEventState state) {
+ long_event(m_instance, event_type, state);
+}
+
+void EngineInstance::positionedEvent(Engine::PositionedEventType event_type,
+ qint32 x, qint32 y) {
+ positioned_event(m_instance, event_type, x, y);
+}
+
+void EngineInstance::renderFrame() { render_frame(m_instance); }
+
+void EngineInstance::setOpenGLContext(QOpenGLContext* context) {
+ currentOpenglContext = context;
+
+ auto size = context->surface()->size();
+ setup_current_gl_context(m_instance, static_cast<quint16>(size.width()),
+ static_cast<quint16>(size.height()),
+ &getProcAddress);
+}
+
+QImage EngineInstance::generatePreview() {
+ Engine::PreviewInfo pinfo;
+
+ generate_preview(m_instance, &pinfo);
+
+ QVector<QRgb> colorTable;
+ colorTable.resize(256);
+ for (int i = 0; i < 256; ++i) colorTable[i] = qRgba(255, 255, 0, i);
+
+ QImage previewImage(pinfo.land, static_cast<int>(pinfo.width),
+ static_cast<int>(pinfo.height), QImage::Format_Indexed8);
+ previewImage.setColorTable(colorTable);
+
+ // Cannot use it here, since QImage refers to original bytes
+ // dispose_preview(m_instance);
+
+ return previewImage;
+}
+
+bool EngineInstance::isValid() const { return m_isValid; }