Compare commits
No commits in common. "6e0cc49826d887324976c7ce56a6dca16b4c0aa1" and "c91bc60cb9ba8a7c333d0243178f1e70d0de9d00" have entirely different histories.
6e0cc49826
...
c91bc60cb9
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.24)
|
|||||||
|
|
||||||
project(RaylibDmx)
|
project(RaylibDmx)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 23)
|
set(CMAKE_CXX_STANDARD 26)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
# nvim/fleet users (ONLY WORKS WITH MINGW/NINJA BUILDERS)
|
# nvim/fleet users (ONLY WORKS WITH MINGW/NINJA BUILDERS)
|
||||||
@ -64,22 +64,19 @@ FetchContent_Declare(
|
|||||||
)
|
)
|
||||||
FetchContent_MakeAvailable(rlimgui)
|
FetchContent_MakeAvailable(rlimgui)
|
||||||
|
|
||||||
# Add source files
|
file(GLOB_RECURSE SOURCES "src/*.cpp")
|
||||||
file(GLOB_RECURSE PROJECT_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_LIST_DIR}/src/*.cpp")
|
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||||
set(PROJECT_INCLUDE "${CMAKE_CURRENT_LIST_DIR}/src")
|
|
||||||
|
|
||||||
# Declare the executable
|
target_link_libraries(${PROJECT_NAME} raylib)
|
||||||
add_executable(${PROJECT_NAME})
|
|
||||||
target_sources(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCES})
|
|
||||||
target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_INCLUDE})
|
|
||||||
|
|
||||||
# Link with Raylib
|
set(RLIMGUI_SOURCES
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE raylib)
|
${rlimgui_SOURCE_DIR}/rlImGui.cpp
|
||||||
|
)
|
||||||
|
|
||||||
# Create rlImGui library
|
# Create rlImGui lib
|
||||||
add_library(rlImGui STATIC ${rlimgui_SOURCE_DIR}/rlImGui.cpp)
|
add_library(rlImGui STATIC ${RLIMGUI_SOURCES})
|
||||||
target_include_directories(rlImGui PUBLIC ${rlimgui_SOURCE_DIR} ${imgui_SOURCE_DIR})
|
target_include_directories(rlImGui PUBLIC ${rlimgui_SOURCE_DIR} ${imgui_SOURCE_DIR})
|
||||||
target_link_libraries(rlImGui PRIVATE raylib ImGui)
|
target_link_libraries(rlImGui raylib ImGui)
|
||||||
|
|
||||||
# Link ImGui and rlImGui with the executable
|
# Link ImGui and rlImGui
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE ImGui rlImGui)
|
target_link_libraries(${PROJECT_NAME} ImGui rlImGui)
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by illyum on 8/15/2024.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "BasicLogger.h"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
// Set default verbosity
|
|
||||||
LogPriority BasicLogger::verbosity = TraceP;
|
|
||||||
|
|
||||||
void BasicLogger::Log(LogPriority priority, const char *message) {
|
|
||||||
if (priority >= verbosity) {
|
|
||||||
switch (priority) {
|
|
||||||
case TraceP: std::cout << "Trace: \t"; break;
|
|
||||||
case DebugP: std::cout << "Debug: \t"; break;
|
|
||||||
case InfoP: std::cout << "Info: \t"; break;
|
|
||||||
case WarnP: std::cout << "Warn: \t"; break;
|
|
||||||
case ErrorP: std::cout << "Error: \t"; break;
|
|
||||||
case FatalP: std::cout << "Fatal: \t"; break;
|
|
||||||
}
|
|
||||||
std::cout << message << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BasicLogger::SetVerbosity(LogPriority new_priority) {
|
|
||||||
verbosity = new_priority;
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by illyum on 8/15/2024.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef BASICLOGGER_H
|
|
||||||
#define BASICLOGGER_H
|
|
||||||
|
|
||||||
|
|
||||||
enum LogPriority {
|
|
||||||
TraceP, DebugP, InfoP, WarnP, ErrorP, FatalP
|
|
||||||
};
|
|
||||||
|
|
||||||
class BasicLogger {
|
|
||||||
private:
|
|
||||||
static LogPriority verbosity;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static void Log(LogPriority priority, const char *message);
|
|
||||||
static void SetVerbosity(LogPriority new_priority);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //BASICLOGGER_H
|
|
@ -1,11 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by illyum on 8/16/2024.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "DmxWriter.h"
|
|
||||||
|
|
||||||
DmxWriter::DmxWriter(DMXEngine& engine) : dmxEngine(engine) {}
|
|
||||||
|
|
||||||
void DmxWriter::setChannel(int channel, unsigned char value) {
|
|
||||||
dmxEngine.setChannelValue(channel, value);
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by illyum on 8/16/2024.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef DMXWRITER_H
|
|
||||||
#define DMXWRITER_H
|
|
||||||
|
|
||||||
#include "dmx.h"
|
|
||||||
|
|
||||||
class DmxWriter {
|
|
||||||
public:
|
|
||||||
DmxWriter(DMXEngine& engine);
|
|
||||||
void setChannel(int channel, unsigned char value);
|
|
||||||
|
|
||||||
private:
|
|
||||||
DMXEngine& dmxEngine;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // DMXWRITER_H
|
|
114
src/dmx.cpp
114
src/dmx.cpp
@ -1,117 +1,3 @@
|
|||||||
//
|
//
|
||||||
// Created by illyum on 8/15/2024.
|
// Created by illyum on 8/15/2024.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "dmx.h"
|
|
||||||
#include <iostream>
|
|
||||||
#include <chrono>
|
|
||||||
#include <thread>
|
|
||||||
#include "windows.h"
|
|
||||||
|
|
||||||
DMXEngine::DMXEngine(const char* portName, int baudRate, int dataSize)
|
|
||||||
: running(false), buffer(dataSize, 0) {
|
|
||||||
hSerial = CreateFileA(portName, GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
|
||||||
if (hSerial == INVALID_HANDLE_VALUE) {
|
|
||||||
std::cerr << "Error opening " << portName << " port" << std::endl;
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
configurePort();
|
|
||||||
}
|
|
||||||
|
|
||||||
DMXEngine::~DMXEngine() {
|
|
||||||
if (running) {
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
CloseHandle(hSerial);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DMXEngine::configurePort() {
|
|
||||||
DCB dcbSerialParams = { 0 };
|
|
||||||
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
|
|
||||||
if (!GetCommState(hSerial, &dcbSerialParams)) {
|
|
||||||
std::cerr << "Error getting COM port state" << std::endl;
|
|
||||||
CloseHandle(hSerial);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
dcbSerialParams.BaudRate = 250000;
|
|
||||||
dcbSerialParams.ByteSize = 8;
|
|
||||||
dcbSerialParams.StopBits = TWOSTOPBITS;
|
|
||||||
dcbSerialParams.Parity = NOPARITY;
|
|
||||||
|
|
||||||
if (!SetCommState(hSerial, &dcbSerialParams)) {
|
|
||||||
std::cerr << "Error setting COM port state" << std::endl;
|
|
||||||
CloseHandle(hSerial);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
COMMTIMEOUTS timeouts = { 0 };
|
|
||||||
timeouts.ReadIntervalTimeout = 50;
|
|
||||||
timeouts.ReadTotalTimeoutConstant = 50;
|
|
||||||
timeouts.ReadTotalTimeoutMultiplier = 10;
|
|
||||||
timeouts.WriteTotalTimeoutConstant = 50;
|
|
||||||
timeouts.WriteTotalTimeoutMultiplier = 10;
|
|
||||||
|
|
||||||
if (!SetCommTimeouts(hSerial, &timeouts)) {
|
|
||||||
std::cerr << "Error setting COM port timeouts" << std::endl;
|
|
||||||
CloseHandle(hSerial);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DMXEngine::start() {
|
|
||||||
running = true;
|
|
||||||
dmxThread = std::thread(dmxThreadFunc, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DMXEngine::stop() {
|
|
||||||
running = false;
|
|
||||||
if (dmxThread.joinable()) {
|
|
||||||
dmxThread.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
DMXEngine::dumpZeros();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DMXEngine::setChannelValue(int channel, unsigned char value) {
|
|
||||||
if (channel >= 0 && channel < buffer.size()) {
|
|
||||||
buffer[channel] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DMXEngine::sendDMXData() {
|
|
||||||
while (running) {
|
|
||||||
// Break condition
|
|
||||||
EscapeCommFunction(hSerial, SETBREAK);
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
||||||
EscapeCommFunction(hSerial, CLRBREAK);
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // MAB
|
|
||||||
|
|
||||||
DWORD bytesWritten;
|
|
||||||
unsigned char startCode = 0;
|
|
||||||
WriteFile(hSerial, &startCode, 1, &bytesWritten, NULL);
|
|
||||||
WriteFile(hSerial, buffer.data(), buffer.size(), &bytesWritten, NULL);
|
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(25));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DMXEngine::dumpZeros() {
|
|
||||||
std::fill(buffer.begin(), buffer.end(), 0);
|
|
||||||
|
|
||||||
EscapeCommFunction(hSerial, SETBREAK);
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
||||||
EscapeCommFunction(hSerial, CLRBREAK);
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // MAB
|
|
||||||
|
|
||||||
DWORD bytesWritten;
|
|
||||||
unsigned char startCode = 0;
|
|
||||||
WriteFile(hSerial, &startCode, 1, &bytesWritten, NULL);
|
|
||||||
WriteFile(hSerial, buffer.data(), buffer.size(), &bytesWritten, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DMXEngine::dmxThreadFunc(DMXEngine* engine) {
|
|
||||||
engine->sendDMXData();
|
|
||||||
}
|
|
||||||
|
37
src/dmx.h
37
src/dmx.h
@ -2,38 +2,7 @@
|
|||||||
// Created by illyum on 8/15/2024.
|
// Created by illyum on 8/15/2024.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef DMX_H
|
#ifndef RAYLIBDMX_DMX_H
|
||||||
#define DMX_H
|
#define RAYLIBDMX_DMX_H
|
||||||
|
|
||||||
#include <vector>
|
#endif //RAYLIBDMX_DMX_H
|
||||||
#include <tuple>
|
|
||||||
#include <atomic>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
struct DMXFixture {
|
|
||||||
unsigned char r, g, b;
|
|
||||||
int channel;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DMXEngine {
|
|
||||||
public:
|
|
||||||
explicit DMXEngine(const char* portName, int baudRate = 250000, int dataSize = 512);
|
|
||||||
~DMXEngine();
|
|
||||||
|
|
||||||
void start();
|
|
||||||
void stop();
|
|
||||||
void setChannelValue(int channel, unsigned char value);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void sendDMXData();
|
|
||||||
void dumpZeros();
|
|
||||||
void configurePort();
|
|
||||||
static void dmxThreadFunc(DMXEngine* engine);
|
|
||||||
|
|
||||||
void* hSerial;
|
|
||||||
std::atomic<bool> running;
|
|
||||||
std::vector<unsigned char> buffer;
|
|
||||||
std::thread dmxThread;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // DMX_H
|
|
||||||
|
77
src/main.cpp
77
src/main.cpp
@ -2,35 +2,20 @@
|
|||||||
#include "rlImGui.h"
|
#include "rlImGui.h"
|
||||||
#include "panel.h"
|
#include "panel.h"
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#include "dmx.h"
|
|
||||||
#include "DmxWriter.h"
|
|
||||||
#include "BasicLogger.h"
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <ctime>
|
|
||||||
|
|
||||||
void DrawImGui();
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
DMXEngine dmxEngine("\\\\.\\COM3");
|
|
||||||
dmxEngine.start();
|
|
||||||
DmxWriter dmxWriter(dmxEngine);
|
|
||||||
|
|
||||||
// Initialize random seed
|
|
||||||
srand(static_cast<unsigned int>(time(0)));
|
|
||||||
|
|
||||||
const int screenWidth = 1920;
|
const int screenWidth = 1920;
|
||||||
const int screenHeight = 1080;
|
const int screenHeight = 1080;
|
||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "DMX Raylib UI");
|
InitWindow(screenWidth, screenHeight, "DMX Raylib UI");
|
||||||
SetTargetFPS(165);
|
SetTargetFPS(60);
|
||||||
|
|
||||||
rlImGuiSetup(true);
|
rlImGuiSetup(true); // Use true for dark theme, false for light theme
|
||||||
|
|
||||||
Panel timelinePanel = {{0, 0, screenWidth * 0.75f, screenHeight * 0.6f}, "Timeline", LIGHTGRAY, DARKGRAY, true};
|
Panel timelinePanel = {{0, 0, screenWidth * 0.75f, screenHeight * 0.6f}, "Timeline", LIGHTGRAY, DARKGRAY, true};
|
||||||
Panel propertiesPanel = {{screenWidth * 0.75f, 0, screenWidth * 0.25f, screenHeight}, "Properties", LIGHTGRAY, DARKGRAY, true};
|
Panel propertiesPanel = {{screenWidth * 0.75f, 0, screenWidth * 0.25f, screenHeight}, "Properties", LIGHTGRAY, DARKGRAY, true};
|
||||||
|
|
||||||
std::string randomColors;
|
|
||||||
|
|
||||||
while (!WindowShouldClose()) {
|
while (!WindowShouldClose()) {
|
||||||
timelinePanel.Update();
|
timelinePanel.Update();
|
||||||
propertiesPanel.Update();
|
propertiesPanel.Update();
|
||||||
@ -38,68 +23,20 @@ int main() {
|
|||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
rlImGuiBegin();
|
||||||
|
bool open = true;
|
||||||
|
ImGui::ShowDemoWindow(&open);
|
||||||
|
rlImGuiEnd();
|
||||||
|
|
||||||
if (timelinePanel.isVisible) timelinePanel.Draw();
|
if (timelinePanel.isVisible) timelinePanel.Draw();
|
||||||
if (propertiesPanel.isVisible) propertiesPanel.Draw();
|
if (propertiesPanel.isVisible) propertiesPanel.Draw();
|
||||||
|
|
||||||
rlImGuiBegin();
|
|
||||||
|
|
||||||
ImGui::Begin("Random Color Clicker");
|
|
||||||
if (ImGui::Button("Random Color!")) {
|
|
||||||
unsigned char r = static_cast<unsigned char>(rand() % 256);
|
|
||||||
unsigned char g = static_cast<unsigned char>(rand() % 256);
|
|
||||||
unsigned char b = static_cast<unsigned char>(rand() % 256);
|
|
||||||
|
|
||||||
dmxWriter.setChannel(0, r);
|
|
||||||
dmxWriter.setChannel(1, g);
|
|
||||||
dmxWriter.setChannel(2, b);
|
|
||||||
|
|
||||||
randomColors = "Sent DMX Color - R: " + std::to_string(r) +
|
|
||||||
", G: " + std::to_string(g) +
|
|
||||||
", B: " + std::to_string(b);
|
|
||||||
}
|
|
||||||
ImGui::Text("%s", randomColors.c_str());
|
|
||||||
|
|
||||||
// End the window
|
|
||||||
ImGui::End();
|
|
||||||
|
|
||||||
rlImGuiEnd();
|
|
||||||
|
|
||||||
// Draw FPS on the screen
|
|
||||||
DrawFPS(3, screenHeight - 20);
|
DrawFPS(3, screenHeight - 20);
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BasicLogger::Log(DebugP, "Stopping DMX Engine...");
|
|
||||||
dmxEngine.stop();
|
|
||||||
|
|
||||||
BasicLogger::Log(DebugP, "Shutting down rlImGui...");
|
|
||||||
rlImGuiShutdown();
|
rlImGuiShutdown();
|
||||||
|
|
||||||
BasicLogger::Log(DebugP, "Closing Window...");
|
|
||||||
CloseWindow();
|
CloseWindow();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawImGui() {
|
|
||||||
rlImGuiBegin();
|
|
||||||
|
|
||||||
// Begin a new window with a title
|
|
||||||
ImGui::Begin("My Custom Window");
|
|
||||||
|
|
||||||
// Add a button with a label
|
|
||||||
if (ImGui::Button("Click Me"))
|
|
||||||
{
|
|
||||||
// Action to be performed when the button is clicked
|
|
||||||
ImGui::Text("Button Clicked!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// End the window
|
|
||||||
ImGui::End();
|
|
||||||
|
|
||||||
// bool open = true;
|
|
||||||
// ImGui::ShowDemoWindow(&open);
|
|
||||||
|
|
||||||
rlImGuiEnd();
|
|
||||||
}
|
|
||||||
|
8
src/winapi_wrapper.h
Normal file
8
src/winapi_wrapper.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
//
|
||||||
|
// Created by illyum on 8/15/2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef RAYLIBDMX_WINAPI_WRAPPER_H
|
||||||
|
#define RAYLIBDMX_WINAPI_WRAPPER_H
|
||||||
|
|
||||||
|
#endif //RAYLIBDMX_WINAPI_WRAPPER_H
|
Loading…
x
Reference in New Issue
Block a user