# HG changeset patch # User unC0Rr # Date 1541602791 -3600 # Node ID 8354b390f1a25750564a32cfcedd1e58fc92ee80 # Parent b273b43b16d23ccb165793aea880a7e38838f625 Some refactoring of qmlfrontend. It now shows land preview generated by hedgewars-engine diff -r b273b43b16d2 -r 8354b390f1a2 .hgignore --- a/.hgignore Wed Nov 07 15:55:32 2018 +0100 +++ b/.hgignore Wed Nov 07 15:59:51 2018 +0100 @@ -16,7 +16,6 @@ *.ppu *.*~ *.core -hedgewars.pro.user config.inc cmake_install.cmake QTfrontend/hwconsts.cpp @@ -83,8 +82,10 @@ xcuserdata *.mode1v3 *.mode2v3 -gameServer2/target -gameServer2/Cargo.lock -gameServer2/gameServer2.iml .idea Testing/ +rust/*/target +*.lock +*.user +*.iml +build-qmlfrontend* diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/CMakeLists.txt --- a/qmlfrontend/CMakeLists.txt Wed Nov 07 15:55:32 2018 +0100 +++ b/qmlfrontend/CMakeLists.txt Wed Nov 07 15:59:51 2018 +0100 @@ -10,11 +10,10 @@ add_executable(${PROJECT_NAME} "main.cpp" "qml.qrc" "hwengine.cpp" "hwengine.h" - "gameconfig.cpp" "gameconfig.h" - "runqueue.cpp" "runqueue.h" - "gameview.cpp" "gameview.h" + "game_config.cpp" "game_config.h" "team.cpp" "team.h" - "previewimageprovider.cpp" "previewimageprovider.h" - "flib.h") + "engine_instance.cpp" "engine_instance.h" + "preview_image_provider.cpp" "preview_image_provider.h" + "engine_interface.h") target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Quick) diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/Page1.qml --- a/qmlfrontend/Page1.qml Wed Nov 07 15:55:32 2018 +0100 +++ b/qmlfrontend/Page1.qml Wed Nov 07 15:59:51 2018 +0100 @@ -3,7 +3,8 @@ Page1Form { tickButton.onClicked: { - item1.tick(100) + + // item1.tick(100) } gameButton.onClicked: { HWEngine.runQuickGame() diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/Page1Form.ui.qml --- a/qmlfrontend/Page1Form.ui.qml Wed Nov 07 15:55:32 2018 +0100 +++ b/qmlfrontend/Page1Form.ui.qml Wed Nov 07 15:59:51 2018 +0100 @@ -5,45 +5,75 @@ import Hedgewars.Engine 1.0 Item { - property alias button1: button1 - property alias previewImage: previewImage - property alias gameButton: gameButton - width: 1024 - height: 800 - property alias tickButton: tickButton - property alias item1: item1 + property alias button1: button1 + property alias previewImage: previewImage + property alias gameButton: gameButton + width: 1024 + height: 800 + property alias tickButton: tickButton + + //property alias item1: item1 + ColumnLayout { + anchors.fill: parent RowLayout { - anchors.horizontalCenter: parent.horizontalCenter - anchors.topMargin: 20 - anchors.top: parent.top + Layout.alignment: Qt.AlignHCenter - Button { - id: button1 - text: qsTr("Preview") - } + Button { + id: button1 + text: qsTr("Preview") + } - Button { - id: gameButton - text: qsTr("Game") - } + Button { + id: gameButton + text: qsTr("Game") + } - Button { - id: tickButton - text: qsTr("Tick") - } + Button { + id: tickButton + text: qsTr("Tick") + } } - Image { + Rectangle { + border.color: "orange" + border.width: 5 + radius: 5 + + Layout.fillWidth: true + Layout.fillHeight: true + + gradient: Gradient { + GradientStop { + position: 0 + color: "lightblue" + } + GradientStop { + position: 0.9 + color: "blue" + } + GradientStop { + position: 0.9 + color: "darkblue" + } + GradientStop { + position: 1.0 + color: "darkblue" + } + } + + Image { id: previewImage - x: 8 - y: 20 - width: 256 - height: 128 + + anchors.fill: parent + anchors.margins: parent.radius source: "qrc:/res/iconTime.png" + fillMode: Image.PreserveAspectFit cache: false + } } - + } + /* GameView { id: item1 x: 8 @@ -51,4 +81,5 @@ width: 1008 height: 638 } + */ } diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/engine_instance.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/engine_instance.cpp Wed Nov 07 15:59:51 2018 +0100 @@ -0,0 +1,14 @@ +#include "engine_instance.h" + +EngineInstance::EngineInstance(QObject *parent) + : QObject(parent), m_instance(Engine::start_engine()) {} + +EngineInstance::~EngineInstance() { Engine::cleanup(m_instance); } + +Engine::PreviewInfo EngineInstance::generatePreview() { + Engine::PreviewInfo pinfo; + + Engine::generate_preview(m_instance, &pinfo); + + return pinfo; +} diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/engine_instance.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/engine_instance.h Wed Nov 07 15:59:51 2018 +0100 @@ -0,0 +1,24 @@ +#ifndef ENGINEINSTANCE_H +#define ENGINEINSTANCE_H + +#include "engine_interface.h" + +#include + +class EngineInstance : public QObject { + Q_OBJECT + public: + explicit EngineInstance(QObject *parent = nullptr); + ~EngineInstance(); + + Engine::PreviewInfo generatePreview(); + + signals: + + public slots: + + private: + Engine::EngineInstance *m_instance; +}; + +#endif // ENGINEINSTANCE_H diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/engine_interface.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/engine_interface.h Wed Nov 07 15:59:51 2018 +0100 @@ -0,0 +1,36 @@ +#ifndef ENGINE_H +#define ENGINE_H + +#include + +#ifdef __cplusplus +namespace Engine { +extern "C" { +#endif + +typedef struct _EngineInstance EngineInstance; + +typedef struct { + uint32_t width; + uint32_t height; + uint8_t hedgehogs_number; + unsigned char* land; +} PreviewInfo; + +typedef uint32_t protocol_version_t(); +typedef EngineInstance* start_engine_t(); +typedef void generate_preview_t(EngineInstance* engine_state, + PreviewInfo* preview); +typedef void cleanup_t(EngineInstance* engine_state); + +extern protocol_version_t* protocol_version; +extern start_engine_t* start_engine; +extern generate_preview_t* generate_preview; +extern cleanup_t* cleanup; + +#ifdef __cplusplus +} +}; +#endif + +#endif // ENGINE_H diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/flib.h --- a/qmlfrontend/flib.h Wed Nov 07 15:55:32 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -#ifndef FLIB_H -#define FLIB_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -enum MessageType { - MSG_PREVIEW, - MSG_PREVIEWHOGCOUNT, - MSG_TONET, - MSG_GAMEFINISHED, -}; - -typedef union string255_ { - struct { - unsigned char s[256]; - }; - struct { - unsigned char len; - unsigned char str[255]; - }; -} string255; - -typedef void RunEngine_t(int argc, const char** argv); -typedef void GameTick_t(uint32_t time_delta); -typedef void ResizeWindow_t(uint32_t width, uint32_t height); -typedef void ipcToEngineRaw_t(const char* msg, uint32_t len); -typedef void ipcSetEngineBarrier_t(); -typedef void ipcRemoveBarrierFromEngineQueue_t(); -typedef bool updateMousePosition_t(int32_t centerX, int32_t centerY, int32_t x, - int32_t y); - -typedef void registerUIMessagesCallback_t( - void* context, - void (*)(void* context, MessageType mt, const char* msg, uint32_t len)); -typedef void flibInit_t(const char* localPrefix, const char* userPrefix); -typedef void flibFree_t(); -typedef void passFlibEvent_t(const char* data); - -#ifdef __cplusplus -} -#endif - -#endif // FLIB_H diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/game_config.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/game_config.cpp Wed Nov 07 15:59:51 2018 +0100 @@ -0,0 +1,81 @@ +#include "game_config.h" + +GameConfig::GameConfig() : m_isPreview(true) { setPreview(m_isPreview); } + +const char** GameConfig::argv() const { + m_argv.resize(m_arguments.size()); + + for (int i = 0; i < m_arguments.size(); ++i) + m_argv[i] = m_arguments[i].data(); + + return m_argv.data(); +} + +int GameConfig::argc() const { return m_arguments.size(); } + +const QList GameConfig::config() const { + QList cfg = m_cfg; + cfg.append("\x01!"); + return cfg; +} + +void GameConfig::clear() { + m_arguments.clear(); + m_cfg.clear(); +} + +void GameConfig::cmdSeed(const QByteArray& seed) { cfgAppend("eseed " + seed); } + +void GameConfig::cmdTheme(const QByteArray& theme) { + cfgAppend("e$theme " + theme); +} + +void GameConfig::cmdMapgen(int mapgen) { + cfgAppend("e$mapgen " + QByteArray::number(mapgen)); +} + +void GameConfig::cmdTeam(const Team& team) { + cfgAppend("eaddteam " + team.color + " " + team.name); + + for (const Hedgehog& h : team.hedgehogs()) { + cfgAppend("eaddhh " + QByteArray::number(h.level) + " " + + QByteArray::number(h.hp) + " " + h.name); + cfgAppend("ehat " + h.hat); + } + cfgAppend( + "eammloadt 9391929422199121032235111001200000000211100101011111000102"); + cfgAppend( + "eammprob 0405040541600655546554464776576666666155510101115411111114"); + cfgAppend( + "eammdelay 0000000000000205500000040007004000000000220000000600020000"); + cfgAppend( + "eammreinf 1311110312111111123114111111111111111211111111111111111111"); + cfgAppend("eammstore"); +} + +bool GameConfig::isPreview() const { return m_isPreview; } + +void GameConfig::setPreview(bool isPreview) { + m_isPreview = isPreview; + + m_arguments.clear(); + + if (m_isPreview) { + m_arguments << "" + << "--internal" + << "--landpreview"; + + } else { + m_arguments << "" + << "--internal" + << "--nomusic"; + } +} + +void GameConfig::cfgAppend(const QByteArray& cmd) { + Q_ASSERT(cmd.size() < 256); + + quint8 len = cmd.size(); + m_cfg.append(QByteArray::fromRawData(reinterpret_cast(&len), 1) + + cmd); +} diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/game_config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/game_config.h Wed Nov 07 15:59:51 2018 +0100 @@ -0,0 +1,36 @@ +#ifndef GAMECONFIG_H +#define GAMECONFIG_H + +#include +#include + +#include "team.h" + +class GameConfig { + public: + explicit GameConfig(); + + const char** argv() const; + int argc() const; + const QList config() const; + + void clear(); + void cmdSeed(const QByteArray& seed); + void cmdTheme(const QByteArray& theme); + void cmdMapgen(int mapgen); + void cmdTeam(const Team& team); + + bool isPreview() const; + void setPreview(bool isPreview); + + private: + mutable QVector m_argv; + QList m_arguments; + QList m_cfg; + QList m_teams; + bool m_isPreview; + + void cfgAppend(const QByteArray& cmd); +}; + +#endif // GAMECONFIG_H diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/game_view.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/game_view.cpp Wed Nov 07 15:59:51 2018 +0100 @@ -0,0 +1,87 @@ +#include "gameview.h" + +#include +#include +#include +#include +#include + +#include "flib.h" + +extern "C" { +extern GameTick_t* flibGameTick; +extern ResizeWindow_t* flibResizeWindow; +extern updateMousePosition_t* flibUpdateMousePosition; +} + +GameView::GameView() : m_delta(0), m_renderer(nullptr), m_windowChanged(true) { + connect(this, &QQuickItem::windowChanged, this, + &GameView::handleWindowChanged); +} + +void GameView::tick(quint32 delta) { + m_delta = delta; + + if (window()) { + QTimer* timer = new QTimer(this); + connect(timer, &QTimer::timeout, window(), &QQuickWindow::update); + timer->start(100); + + // window()->update(); + } +} + +void GameView::handleWindowChanged(QQuickWindow* win) { + if (win) { + connect(win, &QQuickWindow::beforeSynchronizing, this, &GameView::sync, + Qt::DirectConnection); + connect(win, &QQuickWindow::sceneGraphInvalidated, this, &GameView::cleanup, + Qt::DirectConnection); + + win->setClearBeforeRendering(false); + + m_windowChanged = true; + } +} + +void GameView::cleanup() { + if (m_renderer) { + delete m_renderer; + m_renderer = 0; + } +} + +void GameView::sync() { + if (!m_renderer) { + m_renderer = new GameViewRenderer(); + connect(window(), &QQuickWindow::beforeRendering, m_renderer, + &GameViewRenderer::paint, Qt::DirectConnection); + } + + if (m_windowChanged) { + QSize windowSize = window()->size(); + m_renderer->setViewportSize(windowSize * window()->devicePixelRatio()); + m_centerX = windowSize.width() / 2; + m_centerY = windowSize.height() / 2; + } + + QPoint mousePos = mapFromGlobal(QCursor::pos()).toPoint(); + if (flibUpdateMousePosition(m_centerX, m_centerY, mousePos.x(), mousePos.y())) + QCursor::setPos(mapToGlobal(QPointF(m_centerX, m_centerY)).toPoint()); + + m_renderer->tick(m_delta); +} + +GameViewRenderer::~GameViewRenderer() {} + +void GameViewRenderer::setViewportSize(const QSize& size) { + flibResizeWindow(size.width(), size.height()); +} + +void GameViewRenderer::paint() { + if (m_delta == 0) return; + + flibGameTick(m_delta); + + // m_window->resetOpenGLState(); +} diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/game_view.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/game_view.h Wed Nov 07 15:59:51 2018 +0100 @@ -0,0 +1,51 @@ +#ifndef GAMEVIEW_H +#define GAMEVIEW_H + +#include + +#include +#include + +class GameViewRenderer : public QObject, protected QOpenGLFunctions { + Q_OBJECT + public: + GameViewRenderer() : m_delta(0) {} + ~GameViewRenderer(); + + void tick(quint32 delta) { m_delta = delta; } + void setViewportSize(const QSize& size); + + public slots: + void paint(); + + private: + quint32 m_delta; +}; + +class GameView : public QQuickItem { + Q_OBJECT + + public: + GameView(); + + Q_INVOKABLE void tick(quint32 delta); + + signals: + void tChanged(); + + public slots: + void sync(); + void cleanup(); + + private slots: + void handleWindowChanged(QQuickWindow* win); + + private: + quint32 m_delta; + GameViewRenderer* m_renderer; + bool m_windowChanged; + qint32 m_centerX; + qint32 m_centerY; +}; + +#endif // GAMEVIEW_H diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/gameconfig.cpp --- a/qmlfrontend/gameconfig.cpp Wed Nov 07 15:55:32 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -#include "gameconfig.h" - -GameConfig::GameConfig() : m_isPreview(true) { setPreview(m_isPreview); } - -const char** GameConfig::argv() const { - m_argv.resize(m_arguments.size()); - - for (int i = 0; i < m_arguments.size(); ++i) - m_argv[i] = m_arguments[i].data(); - - return m_argv.data(); -} - -int GameConfig::argc() const { return m_arguments.size(); } - -const QList GameConfig::config() const { - QList cfg = m_cfg; - cfg.append("\x01!"); - return cfg; -} - -void GameConfig::clear() { - m_arguments.clear(); - m_cfg.clear(); -} - -void GameConfig::cmdSeed(const QByteArray& seed) { cfgAppend("eseed " + seed); } - -void GameConfig::cmdTheme(const QByteArray& theme) { - cfgAppend("e$theme " + theme); -} - -void GameConfig::cmdMapgen(int mapgen) { - cfgAppend("e$mapgen " + QByteArray::number(mapgen)); -} - -void GameConfig::cmdTeam(const Team& team) { - cfgAppend("eaddteam " + team.color + " " + team.name); - - for (const Hedgehog& h : team.hedgehogs()) { - cfgAppend("eaddhh " + QByteArray::number(h.level) + " " + - QByteArray::number(h.hp) + " " + h.name); - cfgAppend("ehat " + h.hat); - } - cfgAppend( - "eammloadt 9391929422199121032235111001200000000211100101011111000102"); - cfgAppend( - "eammprob 0405040541600655546554464776576666666155510101115411111114"); - cfgAppend( - "eammdelay 0000000000000205500000040007004000000000220000000600020000"); - cfgAppend( - "eammreinf 1311110312111111123114111111111111111211111111111111111111"); - cfgAppend("eammstore"); -} - -bool GameConfig::isPreview() const { return m_isPreview; } - -void GameConfig::setPreview(bool isPreview) { - m_isPreview = isPreview; - - m_arguments.clear(); - - if (m_isPreview) { - m_arguments << "" - << "--internal" - << "--landpreview"; - - } else { - m_arguments << "" - << "--internal" - << "--nomusic"; - } -} - -void GameConfig::cfgAppend(const QByteArray& cmd) { - Q_ASSERT(cmd.size() < 256); - - quint8 len = cmd.size(); - m_cfg.append(QByteArray::fromRawData(reinterpret_cast(&len), 1) + - cmd); -} diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/gameconfig.h --- a/qmlfrontend/gameconfig.h Wed Nov 07 15:55:32 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -#ifndef GAMECONFIG_H -#define GAMECONFIG_H - -#include -#include - -#include "team.h" - -class GameConfig { - public: - explicit GameConfig(); - - const char** argv() const; - int argc() const; - const QList config() const; - - void clear(); - void cmdSeed(const QByteArray& seed); - void cmdTheme(const QByteArray& theme); - void cmdMapgen(int mapgen); - void cmdTeam(const Team& team); - - bool isPreview() const; - void setPreview(bool isPreview); - - private: - mutable QVector m_argv; - QList m_arguments; - QList m_cfg; - QList m_teams; - bool m_isPreview; - - void cfgAppend(const QByteArray& cmd); -}; - -#endif // GAMECONFIG_H diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/gameview.cpp --- a/qmlfrontend/gameview.cpp Wed Nov 07 15:55:32 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -#include "gameview.h" - -#include -#include -#include -#include -#include - -#include "flib.h" - -extern "C" { -extern GameTick_t* flibGameTick; -extern ResizeWindow_t* flibResizeWindow; -extern updateMousePosition_t* flibUpdateMousePosition; -} - -GameView::GameView() : m_delta(0), m_renderer(nullptr), m_windowChanged(true) { - connect(this, &QQuickItem::windowChanged, this, - &GameView::handleWindowChanged); -} - -void GameView::tick(quint32 delta) { - m_delta = delta; - - if (window()) { - QTimer* timer = new QTimer(this); - connect(timer, &QTimer::timeout, window(), &QQuickWindow::update); - timer->start(100); - - // window()->update(); - } -} - -void GameView::handleWindowChanged(QQuickWindow* win) { - if (win) { - connect(win, &QQuickWindow::beforeSynchronizing, this, &GameView::sync, - Qt::DirectConnection); - connect(win, &QQuickWindow::sceneGraphInvalidated, this, &GameView::cleanup, - Qt::DirectConnection); - - win->setClearBeforeRendering(false); - - m_windowChanged = true; - } -} - -void GameView::cleanup() { - if (m_renderer) { - delete m_renderer; - m_renderer = 0; - } -} - -void GameView::sync() { - if (!m_renderer) { - m_renderer = new GameViewRenderer(); - connect(window(), &QQuickWindow::beforeRendering, m_renderer, - &GameViewRenderer::paint, Qt::DirectConnection); - } - - if (m_windowChanged) { - QSize windowSize = window()->size(); - m_renderer->setViewportSize(windowSize * window()->devicePixelRatio()); - m_centerX = windowSize.width() / 2; - m_centerY = windowSize.height() / 2; - } - - QPoint mousePos = mapFromGlobal(QCursor::pos()).toPoint(); - if (flibUpdateMousePosition(m_centerX, m_centerY, mousePos.x(), mousePos.y())) - QCursor::setPos(mapToGlobal(QPointF(m_centerX, m_centerY)).toPoint()); - - m_renderer->tick(m_delta); -} - -GameViewRenderer::~GameViewRenderer() {} - -void GameViewRenderer::setViewportSize(const QSize& size) { - flibResizeWindow(size.width(), size.height()); -} - -void GameViewRenderer::paint() { - if (m_delta == 0) return; - - flibGameTick(m_delta); - - // m_window->resetOpenGLState(); -} diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/gameview.h --- a/qmlfrontend/gameview.h Wed Nov 07 15:55:32 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -#ifndef GAMEVIEW_H -#define GAMEVIEW_H - -#include - -#include -#include - -class GameViewRenderer : public QObject, protected QOpenGLFunctions { - Q_OBJECT - public: - GameViewRenderer() : m_delta(0) {} - ~GameViewRenderer(); - - void tick(quint32 delta) { m_delta = delta; } - void setViewportSize(const QSize& size); - - public slots: - void paint(); - - private: - quint32 m_delta; -}; - -class GameView : public QQuickItem { - Q_OBJECT - - public: - GameView(); - - Q_INVOKABLE void tick(quint32 delta); - - signals: - void tChanged(); - - public slots: - void sync(); - void cleanup(); - - private slots: - void handleWindowChanged(QQuickWindow* win); - - private: - quint32 m_delta; - GameViewRenderer* m_renderer; - bool m_windowChanged; - qint32 m_centerX; - qint32 m_centerY; -}; - -#endif // GAMEVIEW_H diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/hwengine.cpp --- a/qmlfrontend/hwengine.cpp Wed Nov 07 15:55:32 2018 +0100 +++ b/qmlfrontend/hwengine.cpp Wed Nov 07 15:59:51 2018 +0100 @@ -1,72 +1,23 @@ -#include "hwengine.h" - #include #include #include #include -#include "gameview.h" -#include "previewimageprovider.h" -#include "runqueue.h" +#include "engine_instance.h" +#include "engine_interface.h" +#include "game_view.h" +#include "preview_image_provider.h" -extern "C" { -RunEngine_t* flibRunEngine; -GameTick_t* flibGameTick; -ResizeWindow_t* flibResizeWindow; -updateMousePosition_t* flibUpdateMousePosition; -ipcToEngineRaw_t* flibIpcToEngineRaw; -ipcSetEngineBarrier_t* flibIpcSetEngineBarrier; -ipcRemoveBarrierFromEngineQueue_t* flibIpcRemoveBarrierFromEngineQueue; -registerUIMessagesCallback_t* flibRegisterUIMessagesCallback; -flibInit_t* flibInit; -flibFree_t* flibFree; -passFlibEvent_t* flibPassFlibEvent; -} +#include "hwengine.h" HWEngine::HWEngine(QQmlEngine* engine, QObject* parent) : QObject(parent), m_engine(engine), - m_previewProvider(new PreviewImageProvider()), - m_runQueue(new RunQueue(this)) { - qRegisterMetaType("MessageType"); - -#ifdef Q_OS_WIN - QLibrary hwlib("./libhwengine.dll"); -#else - QLibrary hwlib("./libhwengine.so"); -#endif - - if (!hwlib.load()) - qWarning() << "Engine library not found" << hwlib.errorString(); - - flibRunEngine = (RunEngine_t*)hwlib.resolve("RunEngine"); - flibGameTick = (GameTick_t*)hwlib.resolve("GameTick"); - flibResizeWindow = (ResizeWindow_t*)hwlib.resolve("ResizeWindow"); - flibUpdateMousePosition = - (updateMousePosition_t*)hwlib.resolve("updateMousePosition"); - flibIpcToEngineRaw = (ipcToEngineRaw_t*)hwlib.resolve("ipcToEngineRaw"); - flibIpcSetEngineBarrier = - (ipcSetEngineBarrier_t*)hwlib.resolve("ipcSetEngineBarrier"); - flibIpcRemoveBarrierFromEngineQueue = - (ipcRemoveBarrierFromEngineQueue_t*)hwlib.resolve( - "ipcRemoveBarrierFromEngineQueue"); - flibRegisterUIMessagesCallback = (registerUIMessagesCallback_t*)hwlib.resolve( - "registerUIMessagesCallback"); - flibInit = (flibInit_t*)hwlib.resolve("flibInit"); - flibFree = (flibFree_t*)hwlib.resolve("flibFree"); - - flibInit("/usr/home/unC0Rr/Sources/Hedgewars/MainRepo/share/hedgewars/Data", - "/usr/home/unC0Rr/.hedgewars"); - flibRegisterUIMessagesCallback(this, &guiMessagesCallback); - + m_previewProvider(new PreviewImageProvider()) { m_engine->addImageProvider(QLatin1String("preview"), m_previewProvider); - - connect(m_runQueue, &RunQueue::previewIsRendering, this, - &HWEngine::previewIsRendering); - connect(this, &HWEngine::gameFinished, m_runQueue, &RunQueue::onGameFinished); } -HWEngine::~HWEngine() { flibFree(); } +HWEngine::~HWEngine() {} static QObject* hwengine_singletontype_provider(QQmlEngine* engine, QJSEngine* scriptEngine) { @@ -80,44 +31,7 @@ qDebug("HWEngine::exposeToQML"); qmlRegisterSingletonType("Hedgewars.Engine", 1, 0, "HWEngine", hwengine_singletontype_provider); - qmlRegisterType("Hedgewars.Engine", 1, 0, "GameView"); -} - -void HWEngine::guiMessagesCallback(void* context, MessageType mt, - const char* msg, uint32_t len) { - HWEngine* obj = reinterpret_cast(context); - QByteArray b = QByteArray(msg, len); - - qDebug() << "FLIPC in" << mt << " size = " << b.size(); - - QMetaObject::invokeMethod(obj, "engineMessageHandler", Qt::QueuedConnection, - Q_ARG(MessageType, mt), Q_ARG(QByteArray, b)); -} - -void HWEngine::engineMessageHandler(MessageType mt, const QByteArray& msg) { - switch (mt) { - case MSG_PREVIEW: { - qDebug("MSG_PREVIEW"); - m_previewProvider->setPixmap(msg); - emit previewImageChanged(); - break; - } - case MSG_PREVIEWHOGCOUNT: { - qDebug("MSG_PREVIEWHOGCOUNT"); - m_previewHedgehogsCount = static_cast(msg.data()[0]); - emit previewHogCountChanged(m_previewHedgehogsCount); - break; - } - case MSG_TONET: { - qDebug("MSG_TONET"); - break; - } - case MSG_GAMEFINISHED: { - qDebug("MSG_GAMEFINISHED"); - emit gameFinished(); - break; - } - } + // qmlRegisterType("Hedgewars.Engine", 1, 0, "GameView"); } void HWEngine::getPreview() { @@ -125,7 +39,22 @@ m_gameConfig.cmdSeed(m_seed); m_gameConfig.setPreview(true); - m_runQueue->queue(m_gameConfig); + EngineInstance engine; + Engine::PreviewInfo preview = engine.generatePreview(); + + QVector colorTable; + colorTable.resize(256); + for (int i = 0; i < 256; ++i) colorTable[i] = qRgba(255, 255, 0, i); + + QImage previewImage(preview.land, preview.width, preview.height, + QImage::Format_Indexed8); + previewImage.setColorTable(colorTable); + previewImage.detach(); + + m_previewProvider->setImage(previewImage); + + emit previewImageChanged(); + // m_runQueue->queue(m_gameConfig); } void HWEngine::runQuickGame() { @@ -140,7 +69,7 @@ m_gameConfig.cmdTeam(team2); m_gameConfig.setPreview(false); - m_runQueue->queue(m_gameConfig); + // m_runQueue->queue(m_gameConfig); } int HWEngine::previewHedgehogsCount() const { return m_previewHedgehogsCount; } diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/hwengine.h --- a/qmlfrontend/hwengine.h Wed Nov 07 15:55:32 2018 +0100 +++ b/qmlfrontend/hwengine.h Wed Nov 07 15:59:51 2018 +0100 @@ -4,12 +4,11 @@ #include #include -#include "flib.h" -#include "gameconfig.h" +#include "engine_interface.h" +#include "game_config.h" class QQmlEngine; class PreviewImageProvider; -class RunQueue; class HWEngine : public QObject { Q_OBJECT @@ -38,16 +37,9 @@ private: QQmlEngine* m_engine; PreviewImageProvider* m_previewProvider; - RunQueue* m_runQueue; GameConfig m_gameConfig; QByteArray m_seed; int m_previewHedgehogsCount; - - static void guiMessagesCallback(void* context, MessageType mt, - const char* msg, uint32_t len); - - private slots: - void engineMessageHandler(MessageType mt, const QByteArray& msg); }; #endif // HWENGINE_H diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/main.cpp --- a/qmlfrontend/main.cpp Wed Nov 07 15:55:32 2018 +0100 +++ b/qmlfrontend/main.cpp Wed Nov 07 15:59:51 2018 +0100 @@ -1,12 +1,48 @@ +#include #include +#include #include +#include "engine_interface.h" #include "hwengine.h" +namespace Engine { +protocol_version_t* protocol_version; +start_engine_t* start_engine; +generate_preview_t* generate_preview; +cleanup_t* cleanup; +}; // namespace Engine + +void loadEngineLibrary() { +#ifdef Q_OS_WIN + QLibrary hwlib("./libhedgewars_engine.dll"); +#else + QLibrary hwlib("./libhedgewars_engine.so"); +#endif + + if (!hwlib.load()) + qWarning() << "Engine library not found" << hwlib.errorString(); + + Engine::protocol_version = reinterpret_cast( + hwlib.resolve("protocol_version")); + Engine::start_engine = + reinterpret_cast(hwlib.resolve("start_engine")); + Engine::generate_preview = reinterpret_cast( + hwlib.resolve("generate_preview")); + Engine::cleanup = + reinterpret_cast(hwlib.resolve("cleanup")); + + if (Engine::protocol_version) + qDebug() << "Loaded engine library with protocol version" + << Engine::protocol_version(); +} + int main(int argc, char* argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); + loadEngineLibrary(); + QQmlApplicationEngine engine; HWEngine::exposeToQML(); diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/preview_image_provider.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/preview_image_provider.cpp Wed Nov 07 15:59:51 2018 +0100 @@ -0,0 +1,23 @@ +#include "preview_image_provider.h" + +PreviewImageProvider::PreviewImageProvider() + : QQuickImageProvider(QQuickImageProvider::Pixmap) {} + +QPixmap PreviewImageProvider::requestPixmap(const QString &id, QSize *size, + const QSize &requestedSize) { + Q_UNUSED(id); + Q_UNUSED(requestedSize); + + if (size) *size = m_px.size(); + + return m_px; +} + +void PreviewImageProvider::setImage(const QImage &preview) { + m_px = QPixmap::fromImage(preview, Qt::ColorOnly); + // QPixmap pxres(px.size()); + // QPainter p(&pxres); + + // p.fillRect(pxres.rect(), linearGrad); + // p.drawPixmap(0, 0, px); +} diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/preview_image_provider.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qmlfrontend/preview_image_provider.h Wed Nov 07 15:59:51 2018 +0100 @@ -0,0 +1,21 @@ +#ifndef PREVIEWIMAGEPROVIDER_H +#define PREVIEWIMAGEPROVIDER_H + +#include +#include +#include + +class PreviewImageProvider : public QQuickImageProvider { + public: + PreviewImageProvider(); + + QPixmap requestPixmap(const QString &id, QSize *size, + const QSize &requestedSize); + + void setImage(const QImage &preview); + + private: + QPixmap m_px; +}; + +#endif // PREVIEWIMAGEPROVIDER_H diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/previewimageprovider.cpp --- a/qmlfrontend/previewimageprovider.cpp Wed Nov 07 15:55:32 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -#include "previewimageprovider.h" - -PreviewImageProvider::PreviewImageProvider() - : QQuickImageProvider(QQuickImageProvider::Pixmap) {} - -QPixmap PreviewImageProvider::requestPixmap(const QString &id, QSize *size, - const QSize &requestedSize) { - Q_UNUSED(id); - Q_UNUSED(requestedSize); - - if (size) *size = m_px.size(); - - return m_px; -} - -void PreviewImageProvider::setPixmap(const QByteArray &px) { - QVector colorTable; - colorTable.resize(256); - for (int i = 0; i < 256; ++i) colorTable[i] = qRgba(255, 255, 0, i); - - const quint8 *buf = (const quint8 *)px.constData(); - QImage im(buf, 256, 128, QImage::Format_Indexed8); - im.setColorTable(colorTable); - - m_px = QPixmap::fromImage(im, Qt::ColorOnly); - // QPixmap pxres(px.size()); - // QPainter p(&pxres); - - // p.fillRect(pxres.rect(), linearGrad); - // p.drawPixmap(0, 0, px); -} diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/previewimageprovider.h --- a/qmlfrontend/previewimageprovider.h Wed Nov 07 15:55:32 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -#ifndef PREVIEWIMAGEPROVIDER_H -#define PREVIEWIMAGEPROVIDER_H - -#include -#include -#include - -class PreviewImageProvider : public QQuickImageProvider { - public: - PreviewImageProvider(); - - QPixmap requestPixmap(const QString &id, QSize *size, - const QSize &requestedSize); - - void setPixmap(const QByteArray &px); - - private: - QPixmap m_px; -}; - -#endif // PREVIEWIMAGEPROVIDER_H diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/runqueue.cpp --- a/qmlfrontend/runqueue.cpp Wed Nov 07 15:55:32 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -#include "runqueue.h" - -#include "flib.h" - -extern "C" { -extern RunEngine_t* flibRunEngine; -extern ipcToEngineRaw_t* flibIpcToEngineRaw; -extern ipcSetEngineBarrier_t* flibIpcSetEngineBarrier; -extern ipcRemoveBarrierFromEngineQueue_t* flibIpcRemoveBarrierFromEngineQueue; -} - -RunQueue::RunQueue(QObject* parent) - : QObject(parent) -{ -} - -void RunQueue::queue(const GameConfig& config) -{ - m_runQueue.prepend(config); - - flibIpcSetEngineBarrier(); - for (const QByteArray& b : m_runQueue.last().config()) { - flibIpcToEngineRaw(b.data(), b.size()); - } - - if (m_runQueue.size() == 1) - nextRun(); -} - -void RunQueue::onGameFinished() -{ - m_runQueue.pop_front(); - - nextRun(); -} - -void RunQueue::nextRun() -{ - if (!m_runQueue.isEmpty()) { - if (m_runQueue[0].isPreview()) - emit previewIsRendering(); - - flibIpcRemoveBarrierFromEngineQueue(); - - flibRunEngine(m_runQueue[0].argc(), m_runQueue[0].argv()); - } -} diff -r b273b43b16d2 -r 8354b390f1a2 qmlfrontend/runqueue.h --- a/qmlfrontend/runqueue.h Wed Nov 07 15:55:32 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -#ifndef RUNQUEUE_H -#define RUNQUEUE_H - -#include - -#include "gameconfig.h" - -class RunQueue : public QObject { - Q_OBJECT -public: - explicit RunQueue(QObject* parent = nullptr); - - void queue(const GameConfig& config); - -signals: - void previewIsRendering(); - -public slots: - void onGameFinished(); - -private: - QList m_runQueue; - - void nextRun(); -}; - -#endif // RUNQUEUE_H diff -r b273b43b16d2 -r 8354b390f1a2 rust/hedgewars-engine/src/world.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/hedgewars-engine/src/world.rs Wed Nov 07 15:59:51 2018 +0100 @@ -0,0 +1,44 @@ +use integral_geometry::{Point, Rect, Size}; +use land2d::Land2D; +use landgen::{ + outline_template::OutlineTemplate, template_based::TemplatedLandGenerator, + LandGenerationParameters, LandGenerator, +}; +use lfprng::LaggedFibonacciPRNG; + +pub struct World { + random_numbers_gen: LaggedFibonacciPRNG, + preview: Land2D, +} + +impl World { + pub fn new() -> Self { + Self { + random_numbers_gen: LaggedFibonacciPRNG::new(&[]), + preview: Land2D::new(Size::new(0, 0), 0), + } + } + + pub fn preview(&self) -> &Land2D { + &self.preview + } + + pub fn generate_preview(&mut self) { + fn template() -> OutlineTemplate { + let mut template = OutlineTemplate::new(Size::new(4096, 2048)); + template.islands = vec![vec![ + Rect::from_size_coords(100, 2050, 1, 1), + Rect::from_size_coords(100, 500, 400, 1200), + Rect::from_size_coords(3600, 500, 400, 1200), + Rect::from_size_coords(3900, 2050, 1, 1), + ]]; + template.fill_points = vec![Point::new(1, 0)]; + + template + } + + let params = LandGenerationParameters::new(0 as u8, 255, 5, false, false); + let landgen = TemplatedLandGenerator::new(template()); + self.preview = landgen.generate_land(¶ms, &mut self.random_numbers_gen); + } +}