qmlfrontend/engine_instance.cpp
branchhedgeroid
changeset 15510 7030706266df
parent 15217 b32c52c76977
child 15891 d52f5d8e75e6
equal deleted inserted replaced
7861:bc7b6aa5d67a 15510:7030706266df
       
     1 #include "engine_instance.h"
       
     2 
       
     3 #include <QDebug>
       
     4 #include <QLibrary>
       
     5 #include <QOpenGLFunctions>
       
     6 #include <QSurface>
       
     7 
       
     8 static QOpenGLContext* currentOpenglContext = nullptr;
       
     9 extern "C" void (*getProcAddress(const char* fn))() {
       
    10   if (!currentOpenglContext)
       
    11     return nullptr;
       
    12   else
       
    13     return currentOpenglContext->getProcAddress(fn);
       
    14 }
       
    15 
       
    16 EngineInstance::EngineInstance(const QString& libraryPath, QObject* parent)
       
    17     : QObject(parent) {
       
    18   QLibrary hwlib(libraryPath);
       
    19 
       
    20   if (!hwlib.load())
       
    21     qWarning() << "Engine library not found" << hwlib.errorString();
       
    22 
       
    23   hedgewars_engine_protocol_version =
       
    24       reinterpret_cast<Engine::hedgewars_engine_protocol_version_t*>(
       
    25           hwlib.resolve("hedgewars_engine_protocol_version"));
       
    26   start_engine =
       
    27       reinterpret_cast<Engine::start_engine_t*>(hwlib.resolve("start_engine"));
       
    28   generate_preview = reinterpret_cast<Engine::generate_preview_t*>(
       
    29       hwlib.resolve("generate_preview"));
       
    30   dispose_preview = reinterpret_cast<Engine::dispose_preview_t*>(
       
    31       hwlib.resolve("dispose_preview"));
       
    32   cleanup = reinterpret_cast<Engine::cleanup_t*>(hwlib.resolve("cleanup"));
       
    33 
       
    34   send_ipc = reinterpret_cast<Engine::send_ipc_t*>(hwlib.resolve("send_ipc"));
       
    35   read_ipc = reinterpret_cast<Engine::read_ipc_t*>(hwlib.resolve("read_ipc"));
       
    36 
       
    37   setup_current_gl_context =
       
    38       reinterpret_cast<Engine::setup_current_gl_context_t*>(
       
    39           hwlib.resolve("setup_current_gl_context"));
       
    40   render_frame =
       
    41       reinterpret_cast<Engine::render_frame_t*>(hwlib.resolve("render_frame"));
       
    42   advance_simulation = reinterpret_cast<Engine::advance_simulation_t*>(
       
    43       hwlib.resolve("advance_simulation"));
       
    44   move_camera =
       
    45       reinterpret_cast<Engine::move_camera_t*>(hwlib.resolve("move_camera"));
       
    46   simple_event =
       
    47       reinterpret_cast<Engine::simple_event_t*>(hwlib.resolve("simple_event"));
       
    48   long_event =
       
    49       reinterpret_cast<Engine::long_event_t*>(hwlib.resolve("long_event"));
       
    50   positioned_event = reinterpret_cast<Engine::positioned_event_t*>(
       
    51       hwlib.resolve("positioned_event"));
       
    52 
       
    53   m_isValid = hedgewars_engine_protocol_version && start_engine &&
       
    54               generate_preview && dispose_preview && cleanup && send_ipc &&
       
    55               read_ipc && setup_current_gl_context && render_frame &&
       
    56               advance_simulation && move_camera && simple_event && long_event &&
       
    57               positioned_event;
       
    58 
       
    59   emit isValidChanged(m_isValid);
       
    60 
       
    61   if (isValid()) {
       
    62     qDebug() << "Loaded engine library with protocol version"
       
    63              << hedgewars_engine_protocol_version();
       
    64 
       
    65     m_instance = start_engine();
       
    66   } else {
       
    67     qDebug("Engine library load failed");
       
    68   }
       
    69 }
       
    70 
       
    71 EngineInstance::~EngineInstance() {
       
    72   if (m_isValid) cleanup(m_instance);
       
    73 }
       
    74 
       
    75 void EngineInstance::sendConfig(const GameConfig& config) {
       
    76   for (auto b : config.config()) {
       
    77     send_ipc(m_instance, reinterpret_cast<uint8_t*>(b.data()),
       
    78              static_cast<size_t>(b.size()));
       
    79   }
       
    80 }
       
    81 
       
    82 void EngineInstance::advance(quint32 ticks) {
       
    83   advance_simulation(m_instance, ticks);
       
    84 }
       
    85 
       
    86 void EngineInstance::moveCamera(const QPoint& delta) {
       
    87   move_camera(m_instance, delta.x(), delta.y());
       
    88 }
       
    89 
       
    90 void EngineInstance::simpleEvent(Engine::SimpleEventType event_type) {
       
    91   simple_event(m_instance, event_type);
       
    92 }
       
    93 
       
    94 void EngineInstance::longEvent(Engine::LongEventType event_type,
       
    95                                Engine::LongEventState state) {
       
    96   long_event(m_instance, event_type, state);
       
    97 }
       
    98 
       
    99 void EngineInstance::positionedEvent(Engine::PositionedEventType event_type,
       
   100                                      qint32 x, qint32 y) {
       
   101   positioned_event(m_instance, event_type, x, y);
       
   102 }
       
   103 
       
   104 void EngineInstance::renderFrame() { render_frame(m_instance); }
       
   105 
       
   106 void EngineInstance::setOpenGLContext(QOpenGLContext* context) {
       
   107   currentOpenglContext = context;
       
   108 
       
   109   auto size = context->surface()->size();
       
   110   setup_current_gl_context(m_instance, static_cast<quint16>(size.width()),
       
   111                            static_cast<quint16>(size.height()),
       
   112                            &getProcAddress);
       
   113 }
       
   114 
       
   115 QImage EngineInstance::generatePreview() {
       
   116   Engine::PreviewInfo pinfo;
       
   117 
       
   118   generate_preview(m_instance, &pinfo);
       
   119 
       
   120   QVector<QRgb> colorTable;
       
   121   colorTable.resize(256);
       
   122   for (int i = 0; i < 256; ++i) colorTable[i] = qRgba(255, 255, 0, i);
       
   123 
       
   124   QImage previewImage(pinfo.land, static_cast<int>(pinfo.width),
       
   125                       static_cast<int>(pinfo.height), QImage::Format_Indexed8);
       
   126   previewImage.setColorTable(colorTable);
       
   127 
       
   128   // Cannot use it here, since QImage refers to original bytes
       
   129   // dispose_preview(m_instance);
       
   130 
       
   131   return previewImage;
       
   132 }
       
   133 
       
   134 bool EngineInstance::isValid() const { return m_isValid; }