aboutsummaryrefslogtreecommitdiff
path: root/visualization/qmpvisualization.hpp
blob: c0bc067efdf844e4b9c7f67dc1a82bd8dceabfce (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#ifndef QMPVISUALIZATION_H
#define QMPVISUALIZATION_H

#include <stack>
#include <chrono>
#include <thread>
#include <utility>
#include <vector>
#include <smelt.hpp>
#include <smmath.hpp>
#include <smttfont.hpp>
#include "qmpvirtualpiano3d.hpp"
#include "../include/qmpcorepublic.hpp"

class qmpVisualization;
struct MidiVisualEvent
{
    uint32_t tcs, tce;
    uint32_t key, vel;
    uint32_t ch;
};
class qmpVisualization: public qmpPluginIntf, public qmpFuncBaseIntf
{
    friend class CloseHandler;
private:
    qmpPluginAPI *api;
    std::thread *rendererTh;
    std::vector<MidiVisualEvent *>pool;
    smHandler *h, *closeh;
    std::stack<uint32_t> pendingt[16][128], pendingv[16][128];
    SMELT *sm;
    SMTRG tdscn, tdparticles;
    SMTEX chequer, bgtex, particletex, pianotex;
    smTTFont font, font2, fonthdpi;
    qmpVirtualPiano3D *p3d[16];
    smEntity3DBuffer *nebuf;
    smParticleSystem *pss[16][128];
    smPSEmissionPositionGenerator *psepg;
    float pos[3], rot[3], lastx, lasty;
    uint32_t ctc, ctk, elb, lstk, cfr;
    uint32_t cts, cks, ctp, cpbr[16], cpw[16];
    uint32_t rpnid[16], rpnval[16];
    std::chrono::steady_clock::time_point lst;
    double etps;
    bool shouldclose, playing, debug;
    bool rendermode, hidewindow;
    int herh, heh, hfrf;
    int uihb, uihs, uihp, uihr, uihk;
    void(*framecb)(void *, size_t, uint32_t, uint32_t);
    DWORD *fbcont;
    std::vector<std::pair<uint32_t, uint32_t>>tspool;
    int traveld[16][128];
    bool notestatus[16][128], lastnotestatus[16][128];
    int spectra[16][128], spectrar[16][128];
    void drawCube(smvec3d a, smvec3d b, DWORD col, SMTEX tex, int faces = 63);
    void showThread();
    void pushNoteOn(uint32_t tc, uint32_t ch, uint32_t key, uint32_t vel);
    void pushNoteOff(uint32_t tc, uint32_t ch, uint32_t key);
    void updateVisualization3D();
    void updateVisualization2D();

    static qmpVisualization *inst;
public:
    qmpVisualization(qmpPluginAPI *_api);
    ~qmpVisualization();
    void show();
    void close();
    bool update();
    void start();
    void stop();
    void pause();
    void reset();
    void switchToRenderMode(void(*frameCallback)(void *, size_t, uint32_t, uint32_t), bool _hidewindow);

    void init();
    void deinit();
    const char *pluginGetName();
    const char *pluginGetVersion();

    static qmpVisualization *instance();
};

class CMidiVisualHandler: public smHandler
{
private:
    qmpVisualization *p;
public:
    CMidiVisualHandler(qmpVisualization *par)
    {
        p = par;
    }
    bool handlerFunc()
    {
        return p->update();
    }
};

class CloseHandler: public smHandler
{
private:
    qmpVisualization *p;
public:
    CloseHandler(qmpVisualization *par)
    {
        p = par;
    }
public:
    bool handlerFunc()
    {
        std::thread([this]
        {
            p->api->setFuncState("Visualization", false);
            p->close();
        }).detach();
        return false;
    }
};

extern "C" {
    EXPORTSYM qmpPluginIntf *qmpPluginGetInterface(qmpPluginAPI *api)
    {
        return new qmpVisualization(api);
    }
    EXPORTSYM const char *qmpPluginGetAPIRev()
    {
        return QMP_PLUGIN_API_REV;
    }
    EXPORTSYM void switchToRenderMode(void(*frameCallback)(void *, size_t, uint32_t, uint32_t), bool hidewindow)
    {
        if (qmpVisualization::instance())
            qmpVisualization::instance()->switchToRenderMode(frameCallback, hidewindow);
    }
}

#endif // QMPVISUALIZATION_H