diff --git a/CMakeLists.txt b/CMakeLists.txt index dc50a76..4513280 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -145,22 +145,7 @@ if (NOT raylib_FOUND) # If there's none, fetch and build raylib endif() endif() -# raylib-cpp -find_package(raylib_cpp QUIET) -if (NOT raylib_cpp_FOUND) - if (NOT DEFINED RAYLIB_CPP_VERSION) - set(RAYLIB_CPP_VERSION next) - endif() - include(FetchContent) - FetchContent_Declare( - raylib_cpp - GIT_REPOSITORY https://github.com/RobLoach/raylib-cpp.git - GIT_TAG ${RAYLIB_CPP_VERSION} - ) - FetchContent_MakeAvailable(raylib_cpp) -endif() - -target_link_libraries(${GUI_TARGET_NAME} PRIVATE raylib raylib_cpp) +target_link_libraries(${GUI_TARGET_NAME} PRIVATE raylib) # Checks if OSX and links appropriate frameworks (Only required on MacOS) if (APPLE) @@ -176,7 +161,7 @@ set_common_properties(${GUI_TARGET_NAME}) put_targets_into_folder( FOLDER "ThirdParty/raylib" TARGETS - raylib raylib_cpp uninstall + raylib uninstall ) put_targets_into_folder( diff --git a/res/images/sva-logo.png b/res/images/sva-logo.png deleted file mode 100644 index dabd05d..0000000 Binary files a/res/images/sva-logo.png and /dev/null differ diff --git a/src/TickSystem.hpp b/src/TickSystem.hpp new file mode 100644 index 0000000..daa1d3d --- /dev/null +++ b/src/TickSystem.hpp @@ -0,0 +1,28 @@ +#pragma once +#include +#include + +class TickSystem { +private: + std::chrono::duration timer{ 0 }; + std::chrono::duration tickRate; + + std::function callback; +public: + TickSystem(std::chrono::duration tickRateSeconds, std::function func) + : tickRate(tickRateSeconds), callback(func) { + } + + bool update(std::chrono::duration deltaTime) { + timer += deltaTime; + + if (timer >= tickRate) { + timer -= tickRate; + return true; + } + + return false; + } + + void call() const { callback(); } +}; diff --git a/src/collections.hpp b/src/collections.hpp new file mode 100644 index 0000000..7cb580f --- /dev/null +++ b/src/collections.hpp @@ -0,0 +1,138 @@ +#pragma once +#include + + +template +class tree +{ + size_t m_CountBranches = 0; + tree* branches = nullptr; +public: + T value; + + tree() = default; + + ~tree() + { + delete[] branches; + m_CountBranches = 0; + } + + bool operator==(const tree& rhs) const + { + return branches == rhs.branches; + } + + template + explicit tree(Args&&... args) : value(std::forward(args)...) {} + + tree& get(size_t idx) + { + if (m_CountBranches <= idx || !branches) throw std::out_of_range("Index is out of range!"); + return branches[idx]; + } + + void set(size_t idx, const tree* t) + { + if (m_CountBranches >= idx || !t || !branches) throw std::out_of_range("Index is out of range!"); + branches[idx] = *t; + } + + void add(const tree* t) + { + tree* tmp = new tree[m_CountBranches + 1]; + if (branches) { + memcpy(tmp, branches, sizeof(tree) * m_CountBranches); + delete[] branches; + } + branches = tmp; + tmp[m_CountBranches++] = *t; + } + + void set(size_t idx, const T& val) + { + if (m_CountBranches >= idx || !branches) throw std::out_of_range("Index is out of range!"); + branches[idx].value = value; + } + + template + void add(Args&& ...args) + { + tree* tmp = new tree[m_CountBranches + 1]; + if (branches) { + memcpy(tmp, branches, sizeof(tree) * m_CountBranches); + delete[] branches; + } + branches = tmp; + tmp[m_CountBranches++] = tree(std::forward(args)...); + } + + size_t depth() + { + if (branches) return 1; + size_t res = 0; + for (int i = 0; i < m_CountBranches; ++i) + { + res = max(res, branches[i].depth()); + } + return res + 1; + } + + size_t width() const + { + return m_CountBranches; + } + + tree& operator[](size_t idx) + { + return get(idx); + } +}; + +template +struct linked_list +{ + linked_list* next = nullptr; + linked_list* first = nullptr; + T value; + + linked_list() = default; + linked_list(T val) : value(val) {} + ~linked_list() + { + delete next; + } + + bool operator==(const linked_list& rhs) const + { + return + this->first == rhs.first && + this->next == rhs.next && + this->value == rhs.value; + } + + linked_list& put(const T& val) + { + if (!next) + { + next = new linked_list(val); + if (first) + next->first = first; + else + next->first = this; + return *next; + } + next->value = val; + if (first) + next->first = first; + else + next->first = this; + return *next; + } + + size_t depth() + { + if (!next) return 1; + return next->depth() + 1; + } +}; diff --git a/src/main.cpp b/src/main.cpp index a7bcb5c..25d6a77 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,9 +4,17 @@ int main(int argc, char** argv) { printf("Darling, I'm Home!\n"); - - Sortiva app; - app.run(); - +#ifdef _DEBUG + try { +#endif + Sortiva app; + app.run(); +#ifdef _DEBUG + } + catch (std::exception& e) + { + printf("\nError: %s\n\n", e.what()); + } +#endif return 0; } diff --git a/src/sortiva-draw.cpp b/src/sortiva-draw.cpp new file mode 100644 index 0000000..a04be75 --- /dev/null +++ b/src/sortiva-draw.cpp @@ -0,0 +1,202 @@ +#include "sortiva.hpp" + +namespace rl +{ +#include +} + + +constexpr rl::Color sorter_colors[] = { + { 253, 249, 0, 255 }, // Yellow + { 255, 203, 0, 255 }, // Gold + { 255, 161, 0, 255 }, // Orange + { 255, 109, 194, 255 }, // Pink + { 230, 41, 55, 255 }, // Red + { 190, 33, 55, 255 }, // Maroon + { 0, 228, 48, 255 }, // Green + { 0, 158, 47, 255 }, // Lime + { 0, 117, 44, 255 }, // Dark Green + { 102, 191, 255, 255 }, // Sky Blue + { 0, 121, 241, 255 }, // Blue + { 0, 82, 172, 255 }, // Dark Blue + { 255, 0, 255, 255 }, // Magenta + { 200, 122, 255, 255 }, // Purple + { 135, 60, 190, 255 }, // Violet + { 112, 31, 126, 255 }, // Dark Purple + { 211, 176, 131, 255 }, // Beige + { 127, 106, 79, 255 }, // Brown + { 76, 63, 47, 255 }, // Dark Brown +}; + +constexpr int sorter_colors_size = sizeof(sorter_colors) / sizeof(rl::Color); + +constexpr rl::Color sorter_block_colors[] = { + { 200, 200, 200, 255 }, // Light Gray + { 80, 80, 80, 255 }, // Dark Gray +}; + +constexpr int sorter_block_colors_size = sizeof(sorter_block_colors) / sizeof(rl::Color); + + +void Sortiva::draw() +{ + rl::Vector2 margin = { + .x = m_Width * 0.01f, + .y = m_Height * 0.01f + }; + rl::DrawRectangleV(margin, { m_Width - 2 * margin.x, m_Height - 2 * margin.y }, { 60, 60, 60, 255 }); + + + margin = { + .x = m_Width * 0.02f, + .y = m_Height * 0.02f + }; + + // +2 for start points and end points; will be removed later in the function + size_t cvals = m_Steps->size(); + + size_t steps = m_Steps->at(0).depth(); + for (size_t i = 1; i < cvals; ++i) + { + steps = std::min(steps, m_Steps->at(i).depth()); + } + + steps += 1; + + rl::Rectangle plane = { + .x = margin.x, + .y = margin.y, + .width = m_Width - margin.x * 2, + .height = m_Height - margin.y * 2 + }; + + // ui distance values + int w = static_cast(plane.width / static_cast(steps)); + int g = plane.height / static_cast(cvals + 1); + int h = (plane.height - static_cast(cvals - 1) * g) / 2; + int e = w / 2; + + + float pwhd = sqrtf(plane.width * plane.width + plane.height * plane.height); + float pw = plane.width / pwhd - 0.01f; + float ph = plane.height / pwhd; + float l = pw * ph * pwhd * 0.02f; + + for (size_t i = 0; i < steps; ++i) + { + rl::DrawRectangle( + static_cast(i) * w + static_cast(plane.x), + plane.y, + w, + plane.height, + sorter_block_colors[i % sorter_block_colors_size] + ); + } + steps -= 1; + + // colors to values - ratio ; adds high variance to the color selection + int colid = sorter_colors_size / cvals; + + // font settings + constexpr rl::Color textColor = { 0, 0, 0, 255 }; + int l3 = static_cast(l * 3); + +#ifdef _DEBUG + rl::DrawFPS(5, 5); +#endif + + for (int v = 0; v < cvals; ++v) + { + linked_list* list = &m_Steps->at(v); + + uint16_t value = list->value; + rl::Color col = sorter_colors[(v * colid) % sorter_colors_size]; + + + float wf = static_cast(w); + + int s = 0; + for (; list->next; list = list->next) + { + float sf = static_cast(s); + + value = list->value; + uint16_t nvalue = list->next->value; + float y = plane.y + h + g * (value - 1); + float yt = plane.y + h + g * (nvalue - 1); + + + rl::DrawSplineSegmentBezierCubic( + { (sf + 1.f) * wf + plane.x - 1, y }, + { (sf + 2.f) * wf + plane.x, y }, + { (sf + 1.f) * wf + plane.x, yt }, + { (sf + 2.f) * wf + plane.x, yt }, + l, + col + ); + +#ifdef _DEBUG + float font_size = l * 1.2f; + int yd = y - yt < 0 ? -font_size : +font_size; + yd *= 2; + rl::DrawText( + rl::TextFormat("%d -> %d", value, nvalue), + (sf + 1.f) * wf + plane.x + 10, + y + yd, + font_size, + col); +#endif + ++s; + } + + value = list->value; + + rl::Vector2 pos = { wf * steps + e + plane.x, h + (value - 1) * g + plane.y }; + rl::DrawCircleV(pos, l3, col); + + rl::DrawLineEx( + { pos.x - e - 1, pos.y }, + pos, + l, + col + ); + + const char* strv = rl::TextFormat("%d", v + 1); + rl::DrawText( + strv, + static_cast(pos.x) + e / 2, + static_cast(pos.y) - l3 / 2, + l3, + textColor + ); + + list = list->first; + value = list->value; + pos = { wf - e + plane.x, h + (value - 1) * g + plane.y }; + + rl::DrawText( + strv, + static_cast(pos.x) - e / 2 - l3 / 2, + static_cast(pos.y) - l3 / 2, + l3, + textColor + ); + + rl::DrawRing( + pos, + l * 2, + l3, + 20.f, + 340.f, + 10, + col + ); + + rl::DrawLineEx( + pos, + { pos.x + e, pos.y }, + l, + col + ); + } +} \ No newline at end of file diff --git a/src/sortiva-update.cpp b/src/sortiva-update.cpp new file mode 100644 index 0000000..ad9f3a5 --- /dev/null +++ b/src/sortiva-update.cpp @@ -0,0 +1,11 @@ +#include "sortiva.hpp" + +void Sortiva::update(double dt) { + for (auto& ticker : m_TickSystems) + { + if (ticker.update(std::chrono::milliseconds(static_cast(dt)))) + { + ticker.call(); + } + } +} \ No newline at end of file diff --git a/src/sortiva.cpp b/src/sortiva.cpp index 20b45d6..e5ca1eb 100644 --- a/src/sortiva.cpp +++ b/src/sortiva.cpp @@ -3,18 +3,25 @@ #include #include +#include +#include -Sortiva::Sortiva() : wnd(1280, 720, "Sortiva", rl::FLAG_WINDOW_RESIZABLE | rl::FLAG_WINDOW_TRANSPARENT) + +namespace rl { - if (!wnd.IsWindowReady()) - { - printf("Window could not be initialized\n"); - exit(-1); - } - rl::SetWindowState(rl::FLAG_WINDOW_RESIZABLE | rl::FLAG_WINDOW_TRANSPARENT); +#include +} - m_Width = rl::GetScreenWidth(); - m_Height = rl::GetScreenHeight(); + +Sortiva::Sortiva() +{ + rl::InitWindow(1280, 720, "Sortiva"); + if (!rl::IsWindowReady()) exit(2); + + m_Width = rl::GetRenderWidth(); + m_Height = rl::GetRenderHeight(); + rl::SetWindowMinSize(static_cast(1280 * 0.25f), static_cast(720 * 0.25f)); + rl::SetWindowState(rl::ConfigFlags::FLAG_WINDOW_RESIZABLE | rl::ConfigFlags::FLAG_VSYNC_HINT); rl::SetTargetFPS(60); } @@ -39,152 +46,34 @@ void Sortiva::run() rl::ClearBackground({ 25, 25, 25, 255 }); rl::BeginDrawing(); + update(rl::GetFrameTime()); draw(); rl::EndDrawing(); } } -constexpr rl::Color sorter_colors[] = { - { 253, 249, 0, 255 }, // Yellow - { 255, 203, 0, 255 }, // Gold - { 255, 161, 0, 255 }, // Orange - { 255, 109, 194, 255 }, // Pink - { 230, 41, 55, 255 }, // Red - { 190, 33, 55, 255 }, // Maroon - { 0, 228, 48, 255 }, // Green - { 0, 158, 47, 255 }, // Lime - { 0, 117, 44, 255 }, // Dark Green - { 102, 191, 255, 255 }, // Sky Blue - { 0, 121, 241, 255 }, // Blue - { 0, 82, 172, 255 }, // Dark Blue - { 255, 0, 255, 255 }, // Magenta - { 200, 122, 255, 255 }, // Purple - { 135, 60, 190, 255 }, // Violet - { 112, 31, 126, 255 }, // Dark Purple - { 211, 176, 131, 255 }, // Beige - { 127, 106, 79, 255 }, // Brown - { 76, 63, 47, 255 }, // Dark Brown -}; - -constexpr int sorter_colors_size = sizeof(sorter_colors) / sizeof(rl::Color); - -constexpr rl::Color sorter_block_colors[] = { - { 200, 200, 200, 255 }, // Light Gray - { 80, 80, 80, 255 }, // Dark Gray -}; - -constexpr int sorter_block_colors_size = sizeof(sorter_block_colors) / sizeof(rl::Color); - -void Sortiva::draw() -{ - float margin = static_cast(m_Width) / m_Height * 10; - rl::DrawRectangle(1 + margin, 1 + margin, m_Width - 2 * margin, m_Height - 2 * margin, { 60,60,60,255 }); - - margin = static_cast(m_Width) / m_Height * 20; - - - int steps = (m_Steps.size() / m_Values) + 2; - - float hoffset = (static_cast(m_Height) - margin * 2) / static_cast(m_Values); - float woffset = (static_cast(m_Width) - margin * 2) / static_cast(steps); - - for (int i = 0; i < steps; ++i) - { - rl::DrawRectangle( - margin + (woffset * static_cast(i)), - margin, - woffset, - m_Height - 2 * margin, - sorter_block_colors[i % sorter_block_colors_size] - ); - } - - - steps = m_Steps.size() / m_Values; - - // colors to values - ratio ; adds high variance to the color selection - int colid = sorter_colors_size / m_Values; - - // font settings - constexpr rl::Color textColor = RL_COLOR(BLACK); - int fsize = margin; - - for (int i = 0; i < m_Values; ++i) - { - float hp = hoffset * (i + .5f); - rl::Vector2 pos = { margin * 3.f, hp }; - rl::Color col = sorter_colors[(m_Steps[i] * colid) % sorter_colors_size]; - - rl::DrawRing(pos, margin / 4, margin / 2, 20.f, 340.f, 10, col); - - rl::DrawLineEx( - pos, - { woffset + margin, hp }, - margin / 4, - col - ); - - rl::DrawText( - rl::TextFormat("%d", m_Steps[i]), - pos.x - 20 - fsize / 2, - pos.y - fsize / 2, - fsize, - textColor - ); - } - - for (int i = 0; i < m_Values; ++i) - { - float hp = hoffset * (i + .5f); - for (int s = 0; s < steps; ++s) { - rl::DrawLineEx( - { woffset * (s + 1) + margin, hp }, - { woffset * (s + 2) + margin, hp }, - margin / 4, - // calculating the 1d position; multiplies the colors/values ratio - sorter_colors[(m_Steps[(m_Values * s) + i] * colid) % sorter_colors_size] - ); - } - } - - for (int i = 0; i < m_Values; ++i) - { - float hp = hoffset * (i + .5f); - rl::Vector2 pos = { woffset * (steps + 2) - margin, hp }; - rl::Color col = sorter_colors[(m_Steps[m_Values * (steps - 1) + i] * colid) % sorter_colors_size]; - - rl::DrawCircleV(pos, margin / 2, col); - - rl::DrawLineEx( - { woffset * (steps + 1) + margin, hp }, - pos, - margin / 4, - col - ); - - rl::DrawText( - rl::TextFormat("%d", m_Steps[m_Values * (steps - 1) + i]), - pos.x + margin / 2 + fsize / 2, - pos.y - fsize / 2, - fsize, - textColor - ); - } - -} - - - void Sortiva::setup() { - m_Steps.clear(); + m_Steps.reset(); + m_Steps = std::make_unique(); - m_Steps = { - 2,1,3, - 1,2,3, - 3,1,2, - 1,2,3, - }; + + + m_Steps->emplace_back(); + m_Steps->emplace_back(); + m_Steps->emplace_back(); + + linked_list& list1 = m_Steps->at(0); + list1.value = 1; + list1.put(1).put(3).put(1).put(1); + // + linked_list& list2 = m_Steps->at(1); + list2.value = 3; + list2.put(2).put(1).put(3).put(2); + // + linked_list& list3 = m_Steps->at(2); + list3.value = 2; + list3.put(3).put(2).put(2).put(3); } diff --git a/src/sortiva.hpp b/src/sortiva.hpp index 6b7525e..678baed 100644 --- a/src/sortiva.hpp +++ b/src/sortiva.hpp @@ -1,10 +1,8 @@ #pragma once -#include #include - -#include - -namespace rl = raylib; +#include +#include "collections.hpp" +#include "TickSystem.hpp" class Sortiva final { @@ -14,20 +12,22 @@ public: void run(); private: - rl::Window wnd; int m_Width; int m_Height; bool m_Running; - /* - * Draw Functions - */ - void draw(); + void draw(); + void update(double deltatime); void setup(); - int m_Values = 3; + std::vector m_TickSystems; - std::vector m_Steps; + // std::unique_ptr + // -> tree + // -> linked_list + // -> uint16_t + using val_step_diag = std::vector>; + std::unique_ptr m_Steps; };