qmlfrontend/engine_instance.cpp
author unC0Rr
Fri, 19 Apr 2024 17:44:55 +0200
changeset 16010 a73b9770467a
parent 15893 5b3beb90e1a6
child 16016 4933920eba89
permissions -rw-r--r--
Port QML frontend to Qt6, use rendering to framebuffer object
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
14154
8354b390f1a2 Some refactoring of qmlfrontend. It now shows land preview generated by hedgewars-engine
unC0Rr
parents:
diff changeset
     1
#include "engine_instance.h"
8354b390f1a2 Some refactoring of qmlfrontend. It now shows land preview generated by hedgewars-engine
unC0Rr
parents:
diff changeset
     2
14298
00b56ec8b7df Pass opengl context to engine
unC0Rr
parents: 14294
diff changeset
     3
#include <QDebug>
14372
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
     4
#include <QLibrary>
14298
00b56ec8b7df Pass opengl context to engine
unC0Rr
parents: 14294
diff changeset
     5
#include <QOpenGLFunctions>
00b56ec8b7df Pass opengl context to engine
unC0Rr
parents: 14294
diff changeset
     6
#include <QSurface>
00b56ec8b7df Pass opengl context to engine
unC0Rr
parents: 14294
diff changeset
     7
00b56ec8b7df Pass opengl context to engine
unC0Rr
parents: 14294
diff changeset
     8
static QOpenGLContext* currentOpenglContext = nullptr;
15893
5b3beb90e1a6 Implement generation of c header from rust interface, adapt qmlfrontend
unC0Rr
parents: 15891
diff changeset
     9
extern "C" void* getProcAddress(const char* fn) {
14298
00b56ec8b7df Pass opengl context to engine
unC0Rr
parents: 14294
diff changeset
    10
  if (!currentOpenglContext)
00b56ec8b7df Pass opengl context to engine
unC0Rr
parents: 14294
diff changeset
    11
    return nullptr;
00b56ec8b7df Pass opengl context to engine
unC0Rr
parents: 14294
diff changeset
    12
  else
15893
5b3beb90e1a6 Implement generation of c header from rust interface, adapt qmlfrontend
unC0Rr
parents: 15891
diff changeset
    13
    return reinterpret_cast<void*>(currentOpenglContext->getProcAddress(fn));
14298
00b56ec8b7df Pass opengl context to engine
unC0Rr
parents: 14294
diff changeset
    14
}
14294
21be7838a127 Add advance_simulation() function to engine lib, some WIP on frontend
unc0rr
parents: 14290
diff changeset
    15
15891
d52f5d8e75e6 Allow passing data_path from QML
unc0rr
parents: 15217
diff changeset
    16
EngineInstance::EngineInstance(const QString& libraryPath, const QString&dataPath, QObject* parent)
d52f5d8e75e6 Allow passing data_path from QML
unc0rr
parents: 15217
diff changeset
    17
    : QObject(parent), m_instance{nullptr, nullptr} {
14372
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    18
  QLibrary hwlib(libraryPath);
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    19
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    20
  if (!hwlib.load())
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    21
    qWarning() << "Engine library not found" << hwlib.errorString();
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    22
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    23
  hedgewars_engine_protocol_version =
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    24
      reinterpret_cast<Engine::hedgewars_engine_protocol_version_t*>(
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    25
          hwlib.resolve("hedgewars_engine_protocol_version"));
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    26
  start_engine =
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    27
      reinterpret_cast<Engine::start_engine_t*>(hwlib.resolve("start_engine"));
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    28
  generate_preview = reinterpret_cast<Engine::generate_preview_t*>(
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    29
      hwlib.resolve("generate_preview"));
14373
4409344db447 Rework EngineInstance::generatePreview, add preview cleanup function in enginelib
unC0Rr
parents: 14372
diff changeset
    30
  dispose_preview = reinterpret_cast<Engine::dispose_preview_t*>(
4409344db447 Rework EngineInstance::generatePreview, add preview cleanup function in enginelib
unC0Rr
parents: 14372
diff changeset
    31
      hwlib.resolve("dispose_preview"));
14372
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    32
  cleanup = reinterpret_cast<Engine::cleanup_t*>(hwlib.resolve("cleanup"));
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    33
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    34
  send_ipc = reinterpret_cast<Engine::send_ipc_t*>(hwlib.resolve("send_ipc"));
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    35
  read_ipc = reinterpret_cast<Engine::read_ipc_t*>(hwlib.resolve("read_ipc"));
14154
8354b390f1a2 Some refactoring of qmlfrontend. It now shows land preview generated by hedgewars-engine
unC0Rr
parents:
diff changeset
    36
14372
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    37
  setup_current_gl_context =
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    38
      reinterpret_cast<Engine::setup_current_gl_context_t*>(
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    39
          hwlib.resolve("setup_current_gl_context"));
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    40
  render_frame =
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    41
      reinterpret_cast<Engine::render_frame_t*>(hwlib.resolve("render_frame"));
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    42
  advance_simulation = reinterpret_cast<Engine::advance_simulation_t*>(
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    43
      hwlib.resolve("advance_simulation"));
14713
cc6ab1e3f7d5 Allow to move camera around
unc0rr
parents: 14373
diff changeset
    44
  move_camera =
cc6ab1e3f7d5 Allow to move camera around
unc0rr
parents: 14373
diff changeset
    45
      reinterpret_cast<Engine::move_camera_t*>(hwlib.resolve("move_camera"));
14854
aed75d439027 Implement external events approach to input user actions into engine.
unc0rr
parents: 14713
diff changeset
    46
  simple_event =
aed75d439027 Implement external events approach to input user actions into engine.
unc0rr
parents: 14713
diff changeset
    47
      reinterpret_cast<Engine::simple_event_t*>(hwlib.resolve("simple_event"));
aed75d439027 Implement external events approach to input user actions into engine.
unc0rr
parents: 14713
diff changeset
    48
  long_event =
aed75d439027 Implement external events approach to input user actions into engine.
unc0rr
parents: 14713
diff changeset
    49
      reinterpret_cast<Engine::long_event_t*>(hwlib.resolve("long_event"));
aed75d439027 Implement external events approach to input user actions into engine.
unc0rr
parents: 14713
diff changeset
    50
  positioned_event = reinterpret_cast<Engine::positioned_event_t*>(
aed75d439027 Implement external events approach to input user actions into engine.
unc0rr
parents: 14713
diff changeset
    51
      hwlib.resolve("positioned_event"));
14372
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    52
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    53
  m_isValid = hedgewars_engine_protocol_version && start_engine &&
14373
4409344db447 Rework EngineInstance::generatePreview, add preview cleanup function in enginelib
unC0Rr
parents: 14372
diff changeset
    54
              generate_preview && dispose_preview && cleanup && send_ipc &&
4409344db447 Rework EngineInstance::generatePreview, add preview cleanup function in enginelib
unC0Rr
parents: 14372
diff changeset
    55
              read_ipc && setup_current_gl_context && render_frame &&
14854
aed75d439027 Implement external events approach to input user actions into engine.
unc0rr
parents: 14713
diff changeset
    56
              advance_simulation && move_camera && simple_event && long_event &&
aed75d439027 Implement external events approach to input user actions into engine.
unc0rr
parents: 14713
diff changeset
    57
              positioned_event;
aed75d439027 Implement external events approach to input user actions into engine.
unc0rr
parents: 14713
diff changeset
    58
14372
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    59
  emit isValidChanged(m_isValid);
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    60
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    61
  if (isValid()) {
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    62
    qDebug() << "Loaded engine library with protocol version"
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    63
             << hedgewars_engine_protocol_version();
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    64
15893
5b3beb90e1a6 Implement generation of c header from rust interface, adapt qmlfrontend
unC0Rr
parents: 15891
diff changeset
    65
    m_instance = std::unique_ptr<Engine::EngineInstance, Engine::cleanup_t*>(
5b3beb90e1a6 Implement generation of c header from rust interface, adapt qmlfrontend
unC0Rr
parents: 15891
diff changeset
    66
        start_engine(reinterpret_cast<const int8_t*>(dataPath.toUtf8().data())),
5b3beb90e1a6 Implement generation of c header from rust interface, adapt qmlfrontend
unC0Rr
parents: 15891
diff changeset
    67
        cleanup);
14713
cc6ab1e3f7d5 Allow to move camera around
unc0rr
parents: 14373
diff changeset
    68
  } else {
cc6ab1e3f7d5 Allow to move camera around
unc0rr
parents: 14373
diff changeset
    69
    qDebug("Engine library load failed");
14372
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    70
  }
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    71
}
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    72
15891
d52f5d8e75e6 Allow passing data_path from QML
unc0rr
parents: 15217
diff changeset
    73
EngineInstance::~EngineInstance() = default;
14154
8354b390f1a2 Some refactoring of qmlfrontend. It now shows land preview generated by hedgewars-engine
unC0Rr
parents:
diff changeset
    74
14290
92e5682810d4 Prepare to have possibility to pass opengl context to engine
unc0rr
parents: 14271
diff changeset
    75
void EngineInstance::sendConfig(const GameConfig& config) {
14271
1aac8a62be6f Implement send_ipc and read_ipc in engine lib, send_ipc in frontend
unC0Rr
parents: 14154
diff changeset
    76
  for (auto b : config.config()) {
15891
d52f5d8e75e6 Allow passing data_path from QML
unc0rr
parents: 15217
diff changeset
    77
    send_ipc(m_instance.get(), reinterpret_cast<uint8_t*>(b.data()),
14372
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
    78
             static_cast<size_t>(b.size()));
14271
1aac8a62be6f Implement send_ipc and read_ipc in engine lib, send_ipc in frontend
unC0Rr
parents: 14154
diff changeset
    79
  }
1aac8a62be6f Implement send_ipc and read_ipc in engine lib, send_ipc in frontend
unC0Rr
parents: 14154
diff changeset
    80
}
1aac8a62be6f Implement send_ipc and read_ipc in engine lib, send_ipc in frontend
unC0Rr
parents: 14154
diff changeset
    81
14298
00b56ec8b7df Pass opengl context to engine
unC0Rr
parents: 14294
diff changeset
    82
void EngineInstance::advance(quint32 ticks) {
15891
d52f5d8e75e6 Allow passing data_path from QML
unc0rr
parents: 15217
diff changeset
    83
  advance_simulation(m_instance.get(), ticks);
14298
00b56ec8b7df Pass opengl context to engine
unC0Rr
parents: 14294
diff changeset
    84
}
14290
92e5682810d4 Prepare to have possibility to pass opengl context to engine
unc0rr
parents: 14271
diff changeset
    85
14713
cc6ab1e3f7d5 Allow to move camera around
unc0rr
parents: 14373
diff changeset
    86
void EngineInstance::moveCamera(const QPoint& delta) {
15891
d52f5d8e75e6 Allow passing data_path from QML
unc0rr
parents: 15217
diff changeset
    87
  move_camera(m_instance.get(), delta.x(), delta.y());
14713
cc6ab1e3f7d5 Allow to move camera around
unc0rr
parents: 14373
diff changeset
    88
}
cc6ab1e3f7d5 Allow to move camera around
unc0rr
parents: 14373
diff changeset
    89
15217
b32c52c76977 Marry C enums, Qt's metaobject system and QML
unc0rr
parents: 14854
diff changeset
    90
void EngineInstance::simpleEvent(Engine::SimpleEventType event_type) {
15891
d52f5d8e75e6 Allow passing data_path from QML
unc0rr
parents: 15217
diff changeset
    91
  simple_event(m_instance.get(), event_type);
14854
aed75d439027 Implement external events approach to input user actions into engine.
unc0rr
parents: 14713
diff changeset
    92
}
aed75d439027 Implement external events approach to input user actions into engine.
unc0rr
parents: 14713
diff changeset
    93
15217
b32c52c76977 Marry C enums, Qt's metaobject system and QML
unc0rr
parents: 14854
diff changeset
    94
void EngineInstance::longEvent(Engine::LongEventType event_type,
b32c52c76977 Marry C enums, Qt's metaobject system and QML
unc0rr
parents: 14854
diff changeset
    95
                               Engine::LongEventState state) {
15891
d52f5d8e75e6 Allow passing data_path from QML
unc0rr
parents: 15217
diff changeset
    96
  long_event(m_instance.get(), event_type, state);
14854
aed75d439027 Implement external events approach to input user actions into engine.
unc0rr
parents: 14713
diff changeset
    97
}
aed75d439027 Implement external events approach to input user actions into engine.
unc0rr
parents: 14713
diff changeset
    98
15217
b32c52c76977 Marry C enums, Qt's metaobject system and QML
unc0rr
parents: 14854
diff changeset
    99
void EngineInstance::positionedEvent(Engine::PositionedEventType event_type,
b32c52c76977 Marry C enums, Qt's metaobject system and QML
unc0rr
parents: 14854
diff changeset
   100
                                     qint32 x, qint32 y) {
15891
d52f5d8e75e6 Allow passing data_path from QML
unc0rr
parents: 15217
diff changeset
   101
  positioned_event(m_instance.get(), event_type, x, y);
14854
aed75d439027 Implement external events approach to input user actions into engine.
unc0rr
parents: 14713
diff changeset
   102
}
aed75d439027 Implement external events approach to input user actions into engine.
unc0rr
parents: 14713
diff changeset
   103
15891
d52f5d8e75e6 Allow passing data_path from QML
unc0rr
parents: 15217
diff changeset
   104
void EngineInstance::renderFrame() { render_frame(m_instance.get()); }
14290
92e5682810d4 Prepare to have possibility to pass opengl context to engine
unc0rr
parents: 14271
diff changeset
   105
14294
21be7838a127 Add advance_simulation() function to engine lib, some WIP on frontend
unc0rr
parents: 14290
diff changeset
   106
void EngineInstance::setOpenGLContext(QOpenGLContext* context) {
14298
00b56ec8b7df Pass opengl context to engine
unC0Rr
parents: 14294
diff changeset
   107
  currentOpenglContext = context;
00b56ec8b7df Pass opengl context to engine
unC0Rr
parents: 14294
diff changeset
   108
00b56ec8b7df Pass opengl context to engine
unC0Rr
parents: 14294
diff changeset
   109
  auto size = context->surface()->size();
15891
d52f5d8e75e6 Allow passing data_path from QML
unc0rr
parents: 15217
diff changeset
   110
  setup_current_gl_context(m_instance.get(), static_cast<quint16>(size.width()),
14372
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
   111
                           static_cast<quint16>(size.height()),
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
   112
                           &getProcAddress);
14294
21be7838a127 Add advance_simulation() function to engine lib, some WIP on frontend
unc0rr
parents: 14290
diff changeset
   113
}
14290
92e5682810d4 Prepare to have possibility to pass opengl context to engine
unc0rr
parents: 14271
diff changeset
   114
14373
4409344db447 Rework EngineInstance::generatePreview, add preview cleanup function in enginelib
unC0Rr
parents: 14372
diff changeset
   115
QImage EngineInstance::generatePreview() {
14154
8354b390f1a2 Some refactoring of qmlfrontend. It now shows land preview generated by hedgewars-engine
unC0Rr
parents:
diff changeset
   116
  Engine::PreviewInfo pinfo;
8354b390f1a2 Some refactoring of qmlfrontend. It now shows land preview generated by hedgewars-engine
unC0Rr
parents:
diff changeset
   117
15891
d52f5d8e75e6 Allow passing data_path from QML
unc0rr
parents: 15217
diff changeset
   118
  generate_preview(m_instance.get(), &pinfo);
14154
8354b390f1a2 Some refactoring of qmlfrontend. It now shows land preview generated by hedgewars-engine
unC0Rr
parents:
diff changeset
   119
14373
4409344db447 Rework EngineInstance::generatePreview, add preview cleanup function in enginelib
unC0Rr
parents: 14372
diff changeset
   120
  QVector<QRgb> colorTable;
4409344db447 Rework EngineInstance::generatePreview, add preview cleanup function in enginelib
unC0Rr
parents: 14372
diff changeset
   121
  colorTable.resize(256);
4409344db447 Rework EngineInstance::generatePreview, add preview cleanup function in enginelib
unC0Rr
parents: 14372
diff changeset
   122
  for (int i = 0; i < 256; ++i) colorTable[i] = qRgba(255, 255, 0, i);
4409344db447 Rework EngineInstance::generatePreview, add preview cleanup function in enginelib
unC0Rr
parents: 14372
diff changeset
   123
4409344db447 Rework EngineInstance::generatePreview, add preview cleanup function in enginelib
unC0Rr
parents: 14372
diff changeset
   124
  QImage previewImage(pinfo.land, static_cast<int>(pinfo.width),
4409344db447 Rework EngineInstance::generatePreview, add preview cleanup function in enginelib
unC0Rr
parents: 14372
diff changeset
   125
                      static_cast<int>(pinfo.height), QImage::Format_Indexed8);
4409344db447 Rework EngineInstance::generatePreview, add preview cleanup function in enginelib
unC0Rr
parents: 14372
diff changeset
   126
  previewImage.setColorTable(colorTable);
4409344db447 Rework EngineInstance::generatePreview, add preview cleanup function in enginelib
unC0Rr
parents: 14372
diff changeset
   127
4409344db447 Rework EngineInstance::generatePreview, add preview cleanup function in enginelib
unC0Rr
parents: 14372
diff changeset
   128
  // Cannot use it here, since QImage refers to original bytes
15891
d52f5d8e75e6 Allow passing data_path from QML
unc0rr
parents: 15217
diff changeset
   129
  // dispose_preview(m_instance.get());
14373
4409344db447 Rework EngineInstance::generatePreview, add preview cleanup function in enginelib
unC0Rr
parents: 14372
diff changeset
   130
4409344db447 Rework EngineInstance::generatePreview, add preview cleanup function in enginelib
unC0Rr
parents: 14372
diff changeset
   131
  return previewImage;
14154
8354b390f1a2 Some refactoring of qmlfrontend. It now shows land preview generated by hedgewars-engine
unC0Rr
parents:
diff changeset
   132
}
14372
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
   133
b6824a53d4b1 Allow to instantiate HWEngine with different library binaries
unC0Rr
parents: 14298
diff changeset
   134
bool EngineInstance::isValid() const { return m_isValid; }