state save/load working! signal pause/play button added, and speed control is now better.
This commit is contained in:
@@ -44,6 +44,7 @@ namespace VISEQ::APP{
|
|||||||
float speed = 16.0f;
|
float speed = 16.0f;
|
||||||
int gui_selected_midi_out;
|
int gui_selected_midi_out;
|
||||||
};
|
};
|
||||||
|
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(AppSettings, mode, width, height, grid, bpm, fps, speed, gui_selected_midi_out)
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace VISEQ::GRAPH{
|
namespace VISEQ::GRAPH{
|
||||||
|
|||||||
+14
-2
@@ -9,11 +9,23 @@ namespace VISEQ::GRAPH {
|
|||||||
class GraphItem{
|
class GraphItem{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GraphItem() {static int _id; id=_id++;}
|
GraphItem() {newId();}
|
||||||
|
GraphItem(const GraphItem& G) {
|
||||||
|
newId();
|
||||||
|
graphItemType = G.graphItemType;
|
||||||
|
neighbors = G.neighbors;
|
||||||
|
}
|
||||||
std::vector<std::shared_ptr<GraphItem>> neighbors;
|
std::vector<std::shared_ptr<GraphItem>> neighbors;
|
||||||
int id = 0;
|
|
||||||
GraphItemType graphItemType;
|
GraphItemType graphItemType;
|
||||||
|
|
||||||
|
int id = 0;
|
||||||
|
|
||||||
|
void newId(){
|
||||||
|
static int _id;
|
||||||
|
id = _id;
|
||||||
|
_id++;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void draw(Vec2Df mouse, Camera2D cam) {};
|
virtual void draw(Vec2Df mouse, Camera2D cam) {};
|
||||||
virtual GraphItemType getType() {return graphItemType;}
|
virtual GraphItemType getType() {return graphItemType;}
|
||||||
virtual ~GraphItem() = default;
|
virtual ~GraphItem() = default;
|
||||||
|
|||||||
+1
-1
@@ -159,7 +159,7 @@ namespace VISEQ::GRAPH {
|
|||||||
void splitEdges(){
|
void splitEdges(){
|
||||||
for(auto s : split_edges){
|
for(auto s : split_edges){
|
||||||
Vec2Df center = s->end->position.center(s->start->position);
|
Vec2Df center = s->end->position.center(s->start->position);
|
||||||
SPTR_Node cn = addMidiNode(center);
|
SPTR_Node cn = copyNode(std::dynamic_pointer_cast<MidiNode>(s->start), center);
|
||||||
addConnection(s->start, cn);
|
addConnection(s->start, cn);
|
||||||
addConnection(cn, s->end);
|
addConnection(cn, s->end);
|
||||||
remove_edges.push_back(s);
|
remove_edges.push_back(s);
|
||||||
|
|||||||
+32
-6
@@ -83,12 +83,13 @@ int main(){
|
|||||||
std::ifstream f("state.json");
|
std::ifstream f("state.json");
|
||||||
json graph = json::parse(f);
|
json graph = json::parse(f);
|
||||||
|
|
||||||
|
app.settings = graph.at("settings");
|
||||||
|
|
||||||
// app.gm = graph["graphmanager"].get<VISEQ::GRAPH::GraphManager>();
|
// app.gm = graph["graphmanager"].get<VISEQ::GRAPH::GraphManager>();
|
||||||
for(auto n : graph.at("graphmanager").at("nodes")){
|
for(auto n : graph.at("graphmanager").at("nodes")){
|
||||||
std::shared_ptr<MidiNode> mn = n;
|
std::shared_ptr<MidiNode> mn = n;
|
||||||
app.gm.nodes.push_back(mn);
|
app.gm.nodes.push_back(mn);
|
||||||
/*app.gm.addMidiNode(n.at("position").get<Vec2Df>());*/
|
std::cout << std::format("adding node {}", mn->id) << std::endl;
|
||||||
/*app.gm.nodes.back().midi_note_channel = n.at("midi_note_channel").get<int>();*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto e : graph.at("graphmanager").at("edges")){
|
for(auto e : graph.at("graphmanager").at("edges")){
|
||||||
@@ -98,10 +99,30 @@ int main(){
|
|||||||
VEC_SPTR_Node start = app.gm.nodes | RANGE_FILTER([start_id](SPTR_Node n){return n->id == start_id;}) | std::ranges::to<VEC_SPTR_Node>();
|
VEC_SPTR_Node start = app.gm.nodes | RANGE_FILTER([start_id](SPTR_Node n){return n->id == start_id;}) | std::ranges::to<VEC_SPTR_Node>();
|
||||||
VEC_SPTR_Node end = app.gm.nodes | RANGE_FILTER([end_id](SPTR_Node n){return n->id == end_id;}) | std::ranges::to<VEC_SPTR_Node>();
|
VEC_SPTR_Node end = app.gm.nodes | RANGE_FILTER([end_id](SPTR_Node n){return n->id == end_id;}) | std::ranges::to<VEC_SPTR_Node>();
|
||||||
|
|
||||||
if(!start.empty() && !end.empty()) app.gm.addConnection(start.front(), end.front());
|
if(!start.empty() && !end.empty()) {
|
||||||
|
std::cout << std::format("connection {} to {}", start_id, end_id) << std::endl;
|
||||||
|
app.gm.addConnection(start.front(), end.front());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(auto s : graph.at("signalmanager").at("signals")){
|
||||||
|
int start_id = s.at("start").get<int>();
|
||||||
|
int next_id = s.at("next").get<int>();
|
||||||
|
int last_id = s.at("last").get<int>();
|
||||||
|
std::shared_ptr<VISEQ::SIGNAL::Signal> ms = s;
|
||||||
|
|
||||||
|
VEC_SPTR_Node start = app.gm.nodes | RANGE_FILTER([start_id](SPTR_Node n){return n->id == start_id;}) | std::ranges::to<VEC_SPTR_Node>();
|
||||||
|
VEC_SPTR_Node last = app.gm.nodes | RANGE_FILTER([last_id](SPTR_Node n){return n->id == last_id;}) | std::ranges::to<VEC_SPTR_Node>();
|
||||||
|
VEC_SPTR_Node next = app.gm.nodes | RANGE_FILTER([next_id](SPTR_Node n){return n->id == next_id;}) | std::ranges::to<VEC_SPTR_Node>();
|
||||||
|
ms->start = start.front();
|
||||||
|
ms->next = next.front();
|
||||||
|
ms->last = last.front();
|
||||||
|
app.sm.signals.push_back(ms);
|
||||||
|
|
||||||
|
std::cout << std::format("adding signal with start node {}", start_id) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for(int i = 0; i < 4; ++i){
|
for(int i = 0; i < 4; ++i){
|
||||||
app.gm.addMidiNode(Vec2Df{(float)i * app.settings.grid*4 + 7 * app.settings.grid, 2 * app.settings.grid*4});
|
app.gm.addMidiNode(Vec2Df{(float)i * app.settings.grid*4 + 7 * app.settings.grid, 2 * app.settings.grid*4});
|
||||||
@@ -211,14 +232,17 @@ int main(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(mouse_released){
|
if(mouse_released){
|
||||||
|
int n_selected = 0;
|
||||||
for(auto& n : app.gm.nodes){
|
for(auto& n : app.gm.nodes){
|
||||||
if(CheckCollisionPointRec(n->position, selection)) {
|
if(CheckCollisionPointRec(n->position, selection)) {
|
||||||
n->selected = true;
|
n->selected = true;
|
||||||
n->in_rect = false;
|
n->in_rect = false;
|
||||||
|
n_selected++;
|
||||||
} else {
|
} else {
|
||||||
if(!IsKeyDown(KEY_LEFT_SHIFT)) n->selected = false;
|
if(!IsKeyDown(KEY_LEFT_SHIFT)) n->selected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(n_selected > 0) copied_nodes.clear();
|
||||||
selection = (Rectangle){0,0,0,0};
|
selection = (Rectangle){0,0,0,0};
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -308,7 +332,9 @@ int main(){
|
|||||||
} else if(!hovering_connectors.empty()){
|
} else if(!hovering_connectors.empty()){
|
||||||
app.gm.addConnection(connecting_nodes.front(), hovering_connectors.front());
|
app.gm.addConnection(connecting_nodes.front(), hovering_connectors.front());
|
||||||
} else {
|
} else {
|
||||||
SPTR_Node new_node = app.gm.addMidiNode(mouse_pos);
|
//SPTR_Node new_node = app.gm.addMidiNode(mouse_pos);
|
||||||
|
SPTR_Node new_node = app.gm.copyNode(std::dynamic_pointer_cast<MidiNode>(connecting_nodes.front()), mouse_pos);
|
||||||
|
new_node->connecting = false;
|
||||||
app.gm.addConnection(connecting_nodes.front(), new_node);
|
app.gm.addConnection(connecting_nodes.front(), new_node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -421,8 +447,8 @@ int main(){
|
|||||||
EndDrawing();
|
EndDrawing();
|
||||||
}
|
}
|
||||||
|
|
||||||
//std::ofstream file("state.json");
|
std::ofstream file("state.json");
|
||||||
//file << json(app);
|
file << json(app);
|
||||||
|
|
||||||
std::cout << std::setw(4) << json(app) << std::endl;
|
std::cout << std::setw(4) << json(app) << std::endl;
|
||||||
|
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
DrawCircle(connector.x, connector.y, 8.0f, (Color){108, 153, 187, (unsigned char)opacity});
|
DrawCircle(connector.x, connector.y, 8.0f, (Color){108, 153, 187, (unsigned char)opacity});
|
||||||
}
|
}
|
||||||
if(highlighted) DrawCircleLinesV(position, radius+2, (Color){255, 0, 0, 200});
|
if(highlighted) DrawCircleLinesV(position, radius+2, (Color){255, 0, 0, 200});
|
||||||
|
DrawText(std::format("{}", id).c_str(), position.x + 20.0f, position.y + 20.0f, 10, WHITE);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-8
@@ -7,6 +7,7 @@
|
|||||||
#include "midi.h"
|
#include "midi.h"
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <locale>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
@@ -30,6 +31,8 @@ namespace VISEQ::SIGNAL {
|
|||||||
|
|
||||||
VEC_SPTR_Signal signals;
|
VEC_SPTR_Signal signals;
|
||||||
|
|
||||||
|
VEC_SPTR_Signal erase_signals;
|
||||||
|
|
||||||
bool loop = true;
|
bool loop = true;
|
||||||
bool play = false;
|
bool play = false;
|
||||||
|
|
||||||
@@ -72,8 +75,8 @@ namespace VISEQ::SIGNAL {
|
|||||||
signals.back()->start = node;
|
signals.back()->start = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeSignal(int n){
|
void removeSignal(std::shared_ptr<Signal> s){
|
||||||
signals.erase(signals.begin() + n);
|
erase_signals.push_back(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateSignals(){
|
void updateSignals(){
|
||||||
@@ -94,8 +97,8 @@ namespace VISEQ::SIGNAL {
|
|||||||
auto midinode = std::dynamic_pointer_cast<MidiNode>(s->next);
|
auto midinode = std::dynamic_pointer_cast<MidiNode>(s->next);
|
||||||
for(auto &m : midinode->midi_outs){
|
for(auto &m : midinode->midi_outs){
|
||||||
if(m.second.enabled) {
|
if(m.second.enabled) {
|
||||||
if(midinode->send_note) midi.note(m.second.i, midinode->midi_note_channel, midinode->midi_note, midinode->midi_velocity, midinode->midi_gate);
|
if(midinode->send_note) midi.note(m.second.i, midinode->midi_note_channel, (int)Clamp(midinode->midi_note + s->midi_note_offset, 0, 127), midinode->midi_velocity, midinode->midi_gate);
|
||||||
if(midinode->send_cc) midi.cc(m.second.i, midinode->midi_cc_channel, midinode->midi_cc, midinode->midi_cc_value);
|
if(midinode->send_cc) midi.cc(m.second.i, midinode->midi_cc_channel, midinode->midi_cc, (int)Clamp(midinode->midi_cc_value + s->midi_cc_offset, 0, 127));
|
||||||
if(midinode->send_pitch_bend) midi.pitch_bend(m.second.i, midinode->midi_pitch_bend_channel, midinode->midi_pitch_bend);
|
if(midinode->send_pitch_bend) midi.pitch_bend(m.second.i, midinode->midi_pitch_bend_channel, midinode->midi_pitch_bend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,11 +116,17 @@ namespace VISEQ::SIGNAL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void drawSignals(Vec2Df mouse_pos, Camera2D camera){
|
void drawSignals(Vec2Df mouse_pos, Camera2D camera){
|
||||||
for(auto s : signals){
|
mutex->lock();
|
||||||
mutex->lock();
|
if(!erase_signals.empty()){
|
||||||
s->draw(mouse_pos, camera);
|
for(auto s: erase_signals){
|
||||||
mutex->unlock();
|
std::erase(signals, s);
|
||||||
|
}
|
||||||
|
erase_signals.clear();
|
||||||
}
|
}
|
||||||
|
for(auto s : signals){
|
||||||
|
s->draw(mouse_pos, camera);
|
||||||
|
}
|
||||||
|
mutex->unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
+7
-3
@@ -12,7 +12,7 @@ namespace VISEQ::SIGNAL {
|
|||||||
class Signal : public BASE::Movable{
|
class Signal : public BASE::Movable{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Signal();
|
Signal() {}
|
||||||
Signal(Vec2Df position, float r, float _speed, Color color) : Movable(position, Vec2Df(0,0), _speed), radius(r), color(color) {}
|
Signal(Vec2Df position, float r, float _speed, Color color) : Movable(position, Vec2Df(0,0), _speed), radius(r), color(color) {}
|
||||||
|
|
||||||
NODES::SPTR_Node next;
|
NODES::SPTR_Node next;
|
||||||
@@ -22,18 +22,22 @@ namespace VISEQ::SIGNAL {
|
|||||||
NODES::SPTR_Node start;
|
NODES::SPTR_Node start;
|
||||||
|
|
||||||
bool at_target = false;
|
bool at_target = false;
|
||||||
|
bool run = true;
|
||||||
|
|
||||||
float radius;
|
float radius = 8.0f;
|
||||||
|
|
||||||
float multiplier = 1.0f;
|
float multiplier = 1.0f;
|
||||||
|
|
||||||
Color color;
|
Color color;
|
||||||
|
|
||||||
|
int midi_note_offset = 0;
|
||||||
|
int midi_cc_offset = 0;
|
||||||
|
|
||||||
void update(double t_delta){
|
void update(double t_delta){
|
||||||
// 120px / 16th = 1920px / whole note
|
// 120px / 16th = 1920px / whole note
|
||||||
// whole note = 2s at 120bpm
|
// whole note = 2s at 120bpm
|
||||||
// 960px / s
|
// 960px / s
|
||||||
position += direction.norm() * speed * multiplier * (float)t_delta / 1000000.0f;
|
if(run) position += direction.norm() * speed * multiplier * (float)t_delta / 1000000.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Vec2Df mouse, Camera2D cam) {
|
void draw(Vec2Df mouse, Camera2D cam) {
|
||||||
|
|||||||
+27
-1
@@ -56,6 +56,7 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
{"distributionMode", N.distributionMode},
|
{"distributionMode", N.distributionMode},
|
||||||
{"nodeType", N.nodeType},
|
{"nodeType", N.nodeType},
|
||||||
{"midi_note_channel",N.midi_note_channel},
|
{"midi_note_channel",N.midi_note_channel},
|
||||||
|
{"midi_note",N.midi_note},
|
||||||
{"midi_velocity",N.midi_velocity},
|
{"midi_velocity",N.midi_velocity},
|
||||||
{"midi_gate",N.midi_gate},
|
{"midi_gate",N.midi_gate},
|
||||||
{"midi_cc_channel",N.midi_cc_channel},
|
{"midi_cc_channel",N.midi_cc_channel},
|
||||||
@@ -76,6 +77,7 @@ namespace VISEQ::GRAPH::NODES {
|
|||||||
j.at("distributionMode").get_to(N.distributionMode);
|
j.at("distributionMode").get_to(N.distributionMode);
|
||||||
j.at("nodeType").get_to(N.nodeType);
|
j.at("nodeType").get_to(N.nodeType);
|
||||||
j.at("midi_note_channel").get_to(N.midi_note_channel);
|
j.at("midi_note_channel").get_to(N.midi_note_channel);
|
||||||
|
j.at("midi_note").get_to(N.midi_note);
|
||||||
j.at("midi_velocity").get_to(N.midi_velocity);
|
j.at("midi_velocity").get_to(N.midi_velocity);
|
||||||
j.at("midi_gate").get_to(N.midi_gate);
|
j.at("midi_gate").get_to(N.midi_gate);
|
||||||
j.at("midi_cc_channel").get_to(N.midi_cc_channel);
|
j.at("midi_cc_channel").get_to(N.midi_cc_channel);
|
||||||
@@ -164,10 +166,34 @@ namespace VISEQ::BASE{
|
|||||||
|
|
||||||
namespace VISEQ::SIGNAL{
|
namespace VISEQ::SIGNAL{
|
||||||
inline void to_json(json& j, const Signal& G){
|
inline void to_json(json& j, const Signal& G){
|
||||||
j = json{{"position", G.position},{"start",G.start->id},{"speed",G.speed}};
|
std::map<std::string, int> fc = {{"r",G.color.r},{"g",G.color.g},{"b",G.color.b},{"a",G.color.a}};
|
||||||
|
j = json{{"color",fc},{"position", G.position},{"radius",G.radius},{"start",G.start->id},{"next",G.next->id},{"last",G.last->id},{"speed",G.speed},{"midi_note_offset",G.midi_note_offset},{"midi_cc_offset",G.midi_cc_offset},{"multiplier",G.multiplier}};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void from_json(const json& j, Signal& S){
|
||||||
|
|
||||||
|
Color c;
|
||||||
|
c.r = j.at("color")["r"].get<int>();
|
||||||
|
c.g = j.at("color")["g"].get<int>();
|
||||||
|
c.b = j.at("color")["b"].get<int>();
|
||||||
|
c.a = j.at("color")["a"].get<int>();
|
||||||
|
|
||||||
|
j.at("position").get_to<Vec2Df>(S.position);
|
||||||
|
j.at("speed").get_to<float>(S.speed);
|
||||||
|
j.at("radius").get_to<float>(S.radius);
|
||||||
|
j.at("midi_note_offset").get_to(S.midi_note_offset);
|
||||||
|
j.at("midi_cc_offset").get_to(S.midi_cc_offset);
|
||||||
|
|
||||||
|
S.color = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void to_json(json& j, const std::shared_ptr<Signal>& G){
|
inline void to_json(json& j, const std::shared_ptr<Signal>& G){
|
||||||
j = *G;
|
j = *G;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void from_json(const json& j, std::shared_ptr<Signal>& S){
|
||||||
|
S.reset(new Signal(j.get<Signal>()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -147,7 +147,7 @@ namespace VISEQ::APP {
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline void to_json(json& j, const AppState& A){
|
inline void to_json(json& j, const AppState& A){
|
||||||
j = json{{"graphmanager", A.gm}, {"signalmanager", A.sm}};
|
j = json{{"graphmanager", A.gm}, {"signalmanager", A.sm}, {"settings",A.settings}};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void from_json(const json& j, AppState& A){
|
inline void from_json(const json& j, AppState& A){
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
namespace VISEQ::APP::UI{
|
namespace VISEQ::APP::UI{
|
||||||
class AppUI{
|
class AppUI{
|
||||||
@@ -22,6 +23,8 @@ namespace VISEQ::APP::UI{
|
|||||||
GraphManager *gm;
|
GraphManager *gm;
|
||||||
SIGNAL::SignalManager *sm;
|
SIGNAL::SignalManager *sm;
|
||||||
|
|
||||||
|
bool bpm_spinner_edit_mode = false;
|
||||||
|
|
||||||
void init(){
|
void init(){
|
||||||
GuiLoadStyleDark();
|
GuiLoadStyleDark();
|
||||||
}
|
}
|
||||||
@@ -38,8 +41,9 @@ namespace VISEQ::APP::UI{
|
|||||||
const int s_bpm = s_controls + 45;
|
const int s_bpm = s_controls + 45;
|
||||||
GuiLabel((Rectangle){20, (float)s_bpm, 120, 20}, "TIMING");
|
GuiLabel((Rectangle){20, (float)s_bpm, 120, 20}, "TIMING");
|
||||||
GuiLabel((Rectangle){200, (float)s_bpm, 40, 20}, std::format("{}",settings->bpm).c_str());
|
GuiLabel((Rectangle){200, (float)s_bpm, 40, 20}, std::format("{}",settings->bpm).c_str());
|
||||||
float _bpm = (float)settings->bpm;
|
int _bpm = settings->bpm;
|
||||||
GuiSlider((Rectangle){20, (float)s_bpm + 25, 240, 20}, "", "", &_bpm, 1, 300);
|
// GuiSlider((Rectangle){20, (float)s_bpm + 25, 240, 20}, "", "", &_bpm, 1, 300);
|
||||||
|
if(GuiSpinner((Rectangle){20, (float)s_bpm + 25, 240, 20}, "", &_bpm, 1, 300, bpm_spinner_edit_mode)) bpm_spinner_edit_mode = !bpm_spinner_edit_mode;
|
||||||
settings->bpm = _bpm;
|
settings->bpm = _bpm;
|
||||||
|
|
||||||
int s_midi = s_bpm + 75;
|
int s_midi = s_bpm + 75;
|
||||||
@@ -71,13 +75,15 @@ namespace VISEQ::APP::UI{
|
|||||||
|
|
||||||
int signal_configs = 0;
|
int signal_configs = 0;
|
||||||
for(auto &s : sm->signals){
|
for(auto &s : sm->signals){
|
||||||
if(GuiButton((Rectangle){20,(float)s_signal+70 + signal_configs*20, 20, 20},"X")) sm->removeSignal(signal_configs);
|
if(GuiButton((Rectangle){20,(float)s_signal+70 + signal_configs*20, 20, 20},"X")) sm->removeSignal(s);
|
||||||
DrawCircle(55, s_signal+80 + signal_configs*20, 6.0F, s->color);
|
DrawCircle(55, s_signal+80 + signal_configs*20, 6.0F, s->color);
|
||||||
float s_multiplier = round(s->multiplier*10.0f)/10.0f;
|
float s_speed = round(s->speed);
|
||||||
float signal_bpm = settings->bpm * s->multiplier;
|
s->multiplier = settings->bpm / 120.0f;
|
||||||
GuiSlider((Rectangle){70, (float)s_signal+70 + signal_configs*20, 160, 20}, "", std::format("{:.1f}",signal_bpm).c_str(), &s_multiplier, 0.1, 10);
|
float signal_bpm = round(settings->bpm * s->multiplier * (s->speed / settings->speed));
|
||||||
s->multiplier = s_multiplier;
|
GuiSlider((Rectangle){70, (float)s_signal+70 + signal_configs*20, 120, 20}, "", "", &s_speed, 1.0f, 16.0f * settings->grid * 4);
|
||||||
s->speed = settings->speed;
|
GuiLabel((Rectangle){195, (float)s_signal+70 + signal_configs*20, 30, 20}, std::format("{}",signal_bpm).c_str());
|
||||||
|
GuiToggle((Rectangle){240, (float)s_signal+70 + signal_configs*20, 20, 20},"P", &s->run);
|
||||||
|
s->speed = s_speed;
|
||||||
signal_configs++;
|
signal_configs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user