Compare commits
5 Commits
c91bc60cb9
...
6e0cc49826
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6e0cc49826 | ||
![]() |
f8341ff8f2 | ||
![]() |
0858e70121 | ||
![]() |
0f5c1da12f | ||
![]() |
3e73cd63bb |
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.24)
|
||||
|
||||
project(RaylibDmx)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 26)
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# nvim/fleet users (ONLY WORKS WITH MINGW/NINJA BUILDERS)
|
||||
@ -64,19 +64,22 @@ FetchContent_Declare(
|
||||
)
|
||||
FetchContent_MakeAvailable(rlimgui)
|
||||
|
||||
file(GLOB_RECURSE SOURCES "src/*.cpp")
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
# Add source files
|
||||
file(GLOB_RECURSE PROJECT_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_LIST_DIR}/src/*.cpp")
|
||||
set(PROJECT_INCLUDE "${CMAKE_CURRENT_LIST_DIR}/src")
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} raylib)
|
||||
# Declare the executable
|
||||
add_executable(${PROJECT_NAME})
|
||||
target_sources(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCES})
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_INCLUDE})
|
||||
|
||||
set(RLIMGUI_SOURCES
|
||||
${rlimgui_SOURCE_DIR}/rlImGui.cpp
|
||||
)
|
||||
# Link with Raylib
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE raylib)
|
||||
|
||||
# Create rlImGui lib
|
||||
add_library(rlImGui STATIC ${RLIMGUI_SOURCES})
|
||||
# Create rlImGui library
|
||||
add_library(rlImGui STATIC ${rlimgui_SOURCE_DIR}/rlImGui.cpp)
|
||||
target_include_directories(rlImGui PUBLIC ${rlimgui_SOURCE_DIR} ${imgui_SOURCE_DIR})
|
||||
target_link_libraries(rlImGui raylib ImGui)
|
||||
target_link_libraries(rlImGui PRIVATE raylib ImGui)
|
||||
|
||||
# Link ImGui and rlImGui
|
||||
target_link_libraries(${PROJECT_NAME} ImGui rlImGui)
|
||||
# Link ImGui and rlImGui with the executable
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ImGui rlImGui)
|
||||
|
27
src/BasicLogger.cpp
Normal file
27
src/BasicLogger.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// 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;
|
||||
}
|
22
src/BasicLogger.h
Normal file
22
src/BasicLogger.h
Normal file
@ -0,0 +1,22 @@
|
||||
//
|
||||
// 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
|
11
src/DmxWriter.cpp
Normal file
11
src/DmxWriter.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
//
|
||||
// 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);
|
||||
}
|
19
src/DmxWriter.h
Normal file
19
src/DmxWriter.h
Normal file
@ -0,0 +1,19 @@
|
||||
//
|
||||
// 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,3 +1,117 @@
|
||||
//
|
||||
// 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,7 +2,38 @@
|
||||
// Created by illyum on 8/15/2024.
|
||||
//
|
||||
|
||||
#ifndef RAYLIBDMX_DMX_H
|
||||
#define RAYLIBDMX_DMX_H
|
||||
#ifndef DMX_H
|
||||
#define DMX_H
|
||||
|
||||
#endif //RAYLIBDMX_DMX_H
|
||||
#include <vector>
|
||||
#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,20 +2,35 @@
|
||||
#include "rlImGui.h"
|
||||
#include "panel.h"
|
||||
#include "imgui.h"
|
||||
#include "dmx.h"
|
||||
#include "DmxWriter.h"
|
||||
#include "BasicLogger.h"
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
void DrawImGui();
|
||||
|
||||
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 screenHeight = 1080;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "DMX Raylib UI");
|
||||
SetTargetFPS(60);
|
||||
SetTargetFPS(165);
|
||||
|
||||
rlImGuiSetup(true); // Use true for dark theme, false for light theme
|
||||
rlImGuiSetup(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};
|
||||
|
||||
std::string randomColors;
|
||||
|
||||
while (!WindowShouldClose()) {
|
||||
timelinePanel.Update();
|
||||
propertiesPanel.Update();
|
||||
@ -23,20 +38,68 @@ int main() {
|
||||
BeginDrawing();
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
rlImGuiBegin();
|
||||
bool open = true;
|
||||
ImGui::ShowDemoWindow(&open);
|
||||
rlImGuiEnd();
|
||||
|
||||
if (timelinePanel.isVisible) timelinePanel.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);
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
|
||||
BasicLogger::Log(DebugP, "Stopping DMX Engine...");
|
||||
dmxEngine.stop();
|
||||
|
||||
BasicLogger::Log(DebugP, "Shutting down rlImGui...");
|
||||
rlImGuiShutdown();
|
||||
|
||||
BasicLogger::Log(DebugP, "Closing Window...");
|
||||
CloseWindow();
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
//
|
||||
// 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