aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/clay_renderer_SDL3.c347
-rw-r--r--src/clay_renderer_SDL3.h43
-rw-r--r--src/custom_elements.c255
-rw-r--r--src/custom_elements.h32
-rw-r--r--src/main.c270
-rw-r--r--src/ui.c18
-rw-r--r--src/ui.h9
7 files changed, 409 insertions, 565 deletions
diff --git a/src/clay_renderer_SDL3.c b/src/clay_renderer_SDL3.c
deleted file mode 100644
index 7e13859..0000000
--- a/src/clay_renderer_SDL3.c
+++ /dev/null
@@ -1,347 +0,0 @@
-#include "clay_renderer_SDL3.h"
-#include <stdio.h>
-
-/* Global for convenience. Even in 4K this is enough for smooth curves (low radius or rect size coupled with
- * no AA or low resolution might make it appear as jagged curves) */
-static int NUM_CIRCLE_SEGMENTS = 16;
-
-//all rendering is performed by a single SDL call, avoiding multiple RenderRect + plumbing choice for circles.
-static void SDL_Clay_RenderFillRoundedRect(Clay_SDL3RendererData *rendererData, const SDL_FRect rect, const float cornerRadius, const Clay_Color _color) {
- const SDL_FColor color = { _color.r/255, _color.g/255, _color.b/255, _color.a/255 };
-
- int indexCount = 0, vertexCount = 0;
-
- const float minRadius = SDL_min(rect.w, rect.h) / 2.0f;
- const float clampedRadius = SDL_min(cornerRadius, minRadius);
-
- const int numCircleSegments = SDL_max(NUM_CIRCLE_SEGMENTS, (int) clampedRadius * 0.5f);
-
- int totalVertices = 4 + (4 * (numCircleSegments * 2)) + 2*4;
- int totalIndices = 6 + (4 * (numCircleSegments * 3)) + 6*4;
-
- SDL_Vertex vertices[totalVertices];
- int indices[totalIndices];
-
- //define center rectangle
- vertices[vertexCount++] = (SDL_Vertex){ {rect.x + clampedRadius, rect.y + clampedRadius}, color, {0, 0} }; //0 center TL
- vertices[vertexCount++] = (SDL_Vertex){ {rect.x + rect.w - clampedRadius, rect.y + clampedRadius}, color, {1, 0} }; //1 center TR
- vertices[vertexCount++] = (SDL_Vertex){ {rect.x + rect.w - clampedRadius, rect.y + rect.h - clampedRadius}, color, {1, 1} }; //2 center BR
- vertices[vertexCount++] = (SDL_Vertex){ {rect.x + clampedRadius, rect.y + rect.h - clampedRadius}, color, {0, 1} }; //3 center BL
-
- indices[indexCount++] = 0;
- indices[indexCount++] = 1;
- indices[indexCount++] = 3;
- indices[indexCount++] = 1;
- indices[indexCount++] = 2;
- indices[indexCount++] = 3;
-
- //define rounded corners as triangle fans
- const float step = (SDL_PI_F/2) / numCircleSegments;
- for (int i = 0; i < numCircleSegments; i++) {
- const float angle1 = (float)i * step;
- const float angle2 = ((float)i + 1.0f) * step;
-
- for (int j = 0; j < 4; j++) { // Iterate over four corners
- float cx, cy, signX, signY;
-
- switch (j) {
- case 0: cx = rect.x + clampedRadius; cy = rect.y + clampedRadius; signX = -1; signY = -1; break; // Top-left
- case 1: cx = rect.x + rect.w - clampedRadius; cy = rect.y + clampedRadius; signX = 1; signY = -1; break; // Top-right
- case 2: cx = rect.x + rect.w - clampedRadius; cy = rect.y + rect.h - clampedRadius; signX = 1; signY = 1; break; // Bottom-right
- case 3: cx = rect.x + clampedRadius; cy = rect.y + rect.h - clampedRadius; signX = -1; signY = 1; break; // Bottom-left
- default: return;
- }
-
- vertices[vertexCount++] = (SDL_Vertex){ {cx + SDL_cosf(angle1) * clampedRadius * signX, cy + SDL_sinf(angle1) * clampedRadius * signY}, color, {0, 0} };
- vertices[vertexCount++] = (SDL_Vertex){ {cx + SDL_cosf(angle2) * clampedRadius * signX, cy + SDL_sinf(angle2) * clampedRadius * signY}, color, {0, 0} };
-
- indices[indexCount++] = j; // Connect to corresponding central rectangle vertex
- indices[indexCount++] = vertexCount - 2;
- indices[indexCount++] = vertexCount - 1;
- }
- }
-
- //Define edge rectangles
- // Top edge
- vertices[vertexCount++] = (SDL_Vertex){ {rect.x + clampedRadius, rect.y}, color, {0, 0} }; //TL
- vertices[vertexCount++] = (SDL_Vertex){ {rect.x + rect.w - clampedRadius, rect.y}, color, {1, 0} }; //TR
-
- indices[indexCount++] = 0;
- indices[indexCount++] = vertexCount - 2; //TL
- indices[indexCount++] = vertexCount - 1; //TR
- indices[indexCount++] = 1;
- indices[indexCount++] = 0;
- indices[indexCount++] = vertexCount - 1; //TR
- // Right edge
- vertices[vertexCount++] = (SDL_Vertex){ {rect.x + rect.w, rect.y + clampedRadius}, color, {1, 0} }; //RT
- vertices[vertexCount++] = (SDL_Vertex){ {rect.x + rect.w, rect.y + rect.h - clampedRadius}, color, {1, 1} }; //RB
-
- indices[indexCount++] = 1;
- indices[indexCount++] = vertexCount - 2; //RT
- indices[indexCount++] = vertexCount - 1; //RB
- indices[indexCount++] = 2;
- indices[indexCount++] = 1;
- indices[indexCount++] = vertexCount - 1; //RB
- // Bottom edge
- vertices[vertexCount++] = (SDL_Vertex){ {rect.x + rect.w - clampedRadius, rect.y + rect.h}, color, {1, 1} }; //BR
- vertices[vertexCount++] = (SDL_Vertex){ {rect.x + clampedRadius, rect.y + rect.h}, color, {0, 1} }; //BL
-
- indices[indexCount++] = 2;
- indices[indexCount++] = vertexCount - 2; //BR
- indices[indexCount++] = vertexCount - 1; //BL
- indices[indexCount++] = 3;
- indices[indexCount++] = 2;
- indices[indexCount++] = vertexCount - 1; //BL
- // Left edge
- vertices[vertexCount++] = (SDL_Vertex){ {rect.x, rect.y + rect.h - clampedRadius}, color, {0, 1} }; //LB
- vertices[vertexCount++] = (SDL_Vertex){ {rect.x, rect.y + clampedRadius}, color, {0, 0} }; //LT
-
- indices[indexCount++] = 3;
- indices[indexCount++] = vertexCount - 2; //LB
- indices[indexCount++] = vertexCount - 1; //LT
- indices[indexCount++] = 0;
- indices[indexCount++] = 3;
- indices[indexCount++] = vertexCount - 1; //LT
-
- // Render everything
- SDL_RenderGeometry(rendererData->renderer, NULL, vertices, vertexCount, indices, indexCount);
-}
-
-static void SDL_Clay_RenderArc(Clay_SDL3RendererData *rendererData, const SDL_FPoint center, const float radius, const float startAngle, const float endAngle, const float thickness, const Clay_Color color) {
- SDL_SetRenderDrawColor(rendererData->renderer, color.r, color.g, color.b, color.a);
-
- const float radStart = startAngle * (SDL_PI_F / 180.0f);
- const float radEnd = endAngle * (SDL_PI_F / 180.0f);
-
- const int numCircleSegments = SDL_max(NUM_CIRCLE_SEGMENTS, (int)(radius * 1.5f)); //increase circle segments for larger circles, 1.5 is arbitrary.
-
- const float angleStep = (radEnd - radStart) / (float)numCircleSegments;
- const float thicknessStep = 0.4f; //arbitrary value to avoid overlapping lines. Changing THICKNESS_STEP or numCircleSegments might cause artifacts.
-
- for (float t = thicknessStep; t < thickness - thicknessStep; t += thicknessStep) {
- SDL_FPoint points[numCircleSegments + 1];
- const float clampedRadius = SDL_max(radius - t, 1.0f);
-
- for (int i = 0; i <= numCircleSegments; i++) {
- const float angle = radStart + i * angleStep;
- points[i] = (SDL_FPoint){
- SDL_roundf(center.x + SDL_cosf(angle) * clampedRadius),
- SDL_roundf(center.y + SDL_sinf(angle) * clampedRadius) };
- }
- SDL_RenderLines(rendererData->renderer, points, numCircleSegments + 1);
- }
-}
-
-void SDL_Clay_RenderCircle(SDL_Renderer *renderer, float x, float y, float width, float height, float start_angle, float end_angle, const Clay_Color _color) {
- const SDL_FColor color = { _color.r/255, _color.g/255, _color.b/255, _color.a/255 };
- float center_x = x + width / 2;
- float center_y = y + width / 2;
- float min_diameter = width > height ? height : width;
- float radius = min_diameter / 2;
-
- float rad_start = start_angle * (SDL_PI_F / 180.0f);
- float rad_end = end_angle * (SDL_PI_F / 180.0f);
-
- const int segments = SDL_max(16, (int)(radius * 1.5f));
- SDL_Vertex vertices[segments + 1];
-
- int vertexCount = 0, indexCount = 0;
-
- vertices[vertexCount++] = (SDL_Vertex){
- .position = { center_x, center_y },
- .color = color
- };
-
- float angle_step = (rad_end - rad_start) / ((float)segments - 1);
-
- for (int i = 0; i < segments; i++) {
- float angle = rad_start + (float)i * angle_step;
- vertices[vertexCount++] = (SDL_Vertex){
- .position = {
- center_x + radius * SDL_cosf(angle),
- center_y + radius * SDL_sinf(angle)
- },
- .color = color
- };
- }
-
- int indices[segments * 3];
- for (int j = 0; j < segments - 1; j++) {
- indices[indexCount++] = 0;
- indices[indexCount++] = j + 1;
- indices[indexCount++] = (j + 1) % segments + 1;
- }
-
- SDL_RenderGeometry(renderer, NULL, vertices, vertexCount, indices, indexCount);
-}
-
-void SDL_Clay_RenderWaveScreen(SDL_Renderer *renderer, float x, float y, float width, float height, const Clay_Color color, float *point_buffer, size_t buffer_len) {
- SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
- float samples_per_px = (float)buffer_len / width;
-
- for (int px = 0; px < (int)width; px++) {
- size_t start = (size_t)(px * samples_per_px);
- size_t end = (size_t)((px + 1) * samples_per_px);
- if (end >= buffer_len) end = buffer_len - 1;
-
- float minv = 1.0f, maxv = -1.0f;
- for (size_t i = start; i <= end; i++) {
- if (point_buffer[i] < minv) minv = point_buffer[i];
- if (point_buffer[i] > maxv) maxv = point_buffer[i];
- }
-
- float y_min = y + height * (0.5f - 0.5f * maxv);
- float y_max = y + height * (0.5f - 0.5f * minv);
-
- SDL_RenderLine(renderer, x + px, y_min, x + px, y_max);
- }
-}
-
-SDL_Rect currentClippingRectangle;
-
-void SDL_Clay_RenderClayCommands(Clay_SDL3RendererData *rendererData, Clay_RenderCommandArray *rcommands)
-{
- for (int32_t i = 0; i < rcommands->length; i++) {
- Clay_RenderCommand *rcmd = Clay_RenderCommandArray_Get(rcommands, i);
- const Clay_BoundingBox bounding_box = rcmd->boundingBox;
- const SDL_FRect rect = { (int)bounding_box.x, (int)bounding_box.y, (int)bounding_box.width, (int)bounding_box.height };
-
- switch (rcmd->commandType) {
- case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: {
- Clay_RectangleRenderData *config = &rcmd->renderData.rectangle;
- SDL_SetRenderDrawBlendMode(rendererData->renderer, SDL_BLENDMODE_BLEND);
- SDL_SetRenderDrawColor(rendererData->renderer, config->backgroundColor.r, config->backgroundColor.g, config->backgroundColor.b, config->backgroundColor.a);
- if (config->cornerRadius.topLeft > 0) {
- SDL_Clay_RenderFillRoundedRect(rendererData, rect, config->cornerRadius.topLeft, config->backgroundColor);
- } else {
- SDL_RenderFillRect(rendererData->renderer, &rect);
- }
- } break;
- case CLAY_RENDER_COMMAND_TYPE_TEXT: {
- Clay_TextRenderData *config = &rcmd->renderData.text;
- TTF_Font *font = rendererData->fonts[config->fontId];
- TTF_SetFontSize(font, config->fontSize);
- TTF_Text *text = TTF_CreateText(rendererData->textEngine, font, config->stringContents.chars, config->stringContents.length);
- TTF_SetTextColor(text, config->textColor.r, config->textColor.g, config->textColor.b, config->textColor.a);
- TTF_DrawRendererText(text, rect.x, rect.y);
- TTF_DestroyText(text);
- } break;
- case CLAY_RENDER_COMMAND_TYPE_BORDER: {
- Clay_BorderRenderData *config = &rcmd->renderData.border;
-
- const float minRadius = SDL_min(rect.w, rect.h) / 2.0f;
- const Clay_CornerRadius clampedRadii = {
- .topLeft = SDL_min(config->cornerRadius.topLeft, minRadius),
- .topRight = SDL_min(config->cornerRadius.topRight, minRadius),
- .bottomLeft = SDL_min(config->cornerRadius.bottomLeft, minRadius),
- .bottomRight = SDL_min(config->cornerRadius.bottomRight, minRadius)
- };
- //edges
- SDL_SetRenderDrawColor(rendererData->renderer, config->color.r, config->color.g, config->color.b, config->color.a);
- if (config->width.left > 0) {
- const float starting_y = rect.y + clampedRadii.topLeft;
- const float length = rect.h - clampedRadii.topLeft - clampedRadii.bottomLeft;
- SDL_FRect line = { rect.x - 1, starting_y, config->width.left, length };
- SDL_RenderFillRect(rendererData->renderer, &line);
- }
- if (config->width.right > 0) {
- const float starting_x = rect.x + rect.w - (float)config->width.right + 1;
- const float starting_y = rect.y + clampedRadii.topRight;
- const float length = rect.h - clampedRadii.topRight - clampedRadii.bottomRight;
- SDL_FRect line = { starting_x, starting_y, config->width.right, length };
- SDL_RenderFillRect(rendererData->renderer, &line);
- }
- if (config->width.top > 0) {
- const float starting_x = rect.x + clampedRadii.topLeft;
- const float length = rect.w - clampedRadii.topLeft - clampedRadii.topRight;
- SDL_FRect line = { starting_x, rect.y - 1, length, config->width.top };
- SDL_RenderFillRect(rendererData->renderer, &line);
- }
- if (config->width.bottom > 0) {
- const float starting_x = rect.x + clampedRadii.bottomLeft;
- const float starting_y = rect.y + rect.h - (float)config->width.bottom + 1;
- const float length = rect.w - clampedRadii.bottomLeft - clampedRadii.bottomRight;
- SDL_FRect line = { starting_x, starting_y, length, config->width.bottom };
- SDL_SetRenderDrawColor(rendererData->renderer, config->color.r, config->color.g, config->color.b, config->color.a);
- SDL_RenderFillRect(rendererData->renderer, &line);
- }
- //corners
- if (config->cornerRadius.topLeft > 0) {
- const float centerX = rect.x + clampedRadii.topLeft -1;
- const float centerY = rect.y + clampedRadii.topLeft - 1;
- SDL_Clay_RenderArc(rendererData, (SDL_FPoint){centerX, centerY}, clampedRadii.topLeft,
- 180.0f, 270.0f, config->width.top, config->color);
- }
- if (config->cornerRadius.topRight > 0) {
- const float centerX = rect.x + rect.w - clampedRadii.topRight;
- const float centerY = rect.y + clampedRadii.topRight - 1;
- SDL_Clay_RenderArc(rendererData, (SDL_FPoint){centerX, centerY}, clampedRadii.topRight,
- 270.0f, 360.0f, config->width.top, config->color);
- }
- if (config->cornerRadius.bottomLeft > 0) {
- const float centerX = rect.x + clampedRadii.bottomLeft -1;
- const float centerY = rect.y + rect.h - clampedRadii.bottomLeft;
- SDL_Clay_RenderArc(rendererData, (SDL_FPoint){centerX, centerY}, clampedRadii.bottomLeft,
- 90.0f, 180.0f, config->width.bottom, config->color);
- }
- if (config->cornerRadius.bottomRight > 0) {
- const float centerX = rect.x + rect.w - clampedRadii.bottomRight;
- const float centerY = rect.y + rect.h - clampedRadii.bottomRight;
- SDL_Clay_RenderArc(rendererData, (SDL_FPoint){centerX, centerY}, clampedRadii.bottomRight,
- 0.0f, 90.0f, config->width.bottom, config->color);
- }
-
- } break;
- case CLAY_RENDER_COMMAND_TYPE_SCISSOR_START: {
- Clay_BoundingBox boundingBox = rcmd->boundingBox;
- currentClippingRectangle = (SDL_Rect) {
- .x = boundingBox.x,
- .y = boundingBox.y,
- .w = boundingBox.width,
- .h = boundingBox.height,
- };
- SDL_SetRenderClipRect(rendererData->renderer, &currentClippingRectangle);
- break;
- }
- case CLAY_RENDER_COMMAND_TYPE_SCISSOR_END: {
- SDL_SetRenderClipRect(rendererData->renderer, NULL);
- break;
- }
- case CLAY_RENDER_COMMAND_TYPE_IMAGE: {
- SDL_Texture *texture = (SDL_Texture *)rcmd->renderData.image.imageData;
- const SDL_FRect dest = { rect.x, rect.y, rect.w, rect.h };
- SDL_RenderTexture(rendererData->renderer, texture, NULL, &dest);
- break;
- }
-
- case CLAY_RENDER_COMMAND_TYPE_CUSTOM: {
- Clay_BoundingBox bounding_box = rcmd->boundingBox;
-
- CustomElementData *custom_element = rcmd->renderData.custom.customData;
- if (!custom_element) continue;
-
- switch (custom_element->type) {
- case CUSTOM_ELEMENT_TYPE_CIRCLE: {
- CircleData config = custom_element->circle;
-
- float start_angle = config.start_angle;
- float end_angle = config.value * 360 + start_angle;
- end_angle = end_angle > start_angle ? end_angle : end_angle + 360;
-
- SDL_Clay_RenderCircle(rendererData->renderer, bounding_box.x, bounding_box.y, bounding_box.width, bounding_box.height, start_angle, end_angle, config.color);
- break;
- }
- case CUSTOM_ELEMENT_TYPE_WAVE_SCREEN: {
- WaveScreenData config = custom_element->wave_screen;
- SDL_Clay_RenderWaveScreen(rendererData->renderer, bounding_box.x, bounding_box.y,
- bounding_box.width, bounding_box.height, config.color,
- config.point_buffer, config.buffer_len);
- }
- }
- break;
- }
- default:
- SDL_Log("Unknown render command type: %d", rcmd->commandType);
- }
- }
-}
diff --git a/src/clay_renderer_SDL3.h b/src/clay_renderer_SDL3.h
deleted file mode 100644
index 5ba1104..0000000
--- a/src/clay_renderer_SDL3.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef RENDERER_H_
-#define RENDERER_H_
-
-#include "clay.h"
-#include <SDL3/SDL.h>
-#include <SDL3_ttf/SDL_ttf.h>
-#include <SDL3_image/SDL_image.h>
-
-typedef struct {
- SDL_Renderer *renderer;
- TTF_TextEngine *textEngine;
- TTF_Font **fonts;
-} Clay_SDL3RendererData;
-
-typedef enum {
- CUSTOM_ELEMENT_TYPE_CIRCLE,
- CUSTOM_ELEMENT_TYPE_WAVE_SCREEN,
-} CustomElementType;
-
-typedef struct {
- float start_angle;
- float value;
- Clay_Color color;
-} CircleData;
-
-typedef struct {
- float *point_buffer;
- size_t buffer_len;
- Clay_Color color;
-} WaveScreenData;
-
-typedef struct {
- CustomElementType type;
-
- union {
- CircleData circle;
- WaveScreenData wave_screen;
- };
-} CustomElementData;
-
-void SDL_Clay_RenderClayCommands(Clay_SDL3RendererData *rendererData, Clay_RenderCommandArray *rcommands);
-
-#endif // RENDERER_H_
diff --git a/src/custom_elements.c b/src/custom_elements.c
new file mode 100644
index 0000000..23a9824
--- /dev/null
+++ b/src/custom_elements.c
@@ -0,0 +1,255 @@
+#include "custom_elements.h"
+
+#include "sokol/sokol_gfx.h"
+#include "sokol/sokol_gl.h"
+#include <stdio.h>
+#include <math.h>
+
+#define STEP_AMOUNT 128
+
+typedef struct {
+ float x;
+ float y;
+} Vec2;
+
+static float _SIN_FULL[128] = {
+ 0.000000f, 0.049068f, 0.098017f, 0.146730f,
+ 0.195090f, 0.242980f, 0.290285f, 0.336890f,
+ 0.382683f, 0.427555f, 0.471397f, 0.514103f,
+ 0.555570f, 0.595699f, 0.634393f, 0.671559f,
+ 0.707107f, 0.740951f, 0.773010f, 0.803208f,
+ 0.831470f, 0.857729f, 0.881921f, 0.903989f,
+ 0.923880f, 0.941544f, 0.956940f, 0.970031f,
+ 0.980785f, 0.989177f, 0.995185f, 0.998795f,
+ 1.000000f, 0.998795f, 0.995185f, 0.989177f,
+ 0.980785f, 0.970031f, 0.956940f, 0.941544f,
+ 0.923880f, 0.903989f, 0.881921f, 0.857729f,
+ 0.831470f, 0.803208f, 0.773010f, 0.740951f,
+ 0.707107f, 0.671559f, 0.634393f, 0.595699f,
+ 0.555570f, 0.514103f, 0.471397f, 0.427555f,
+ 0.382683f, 0.336890f, 0.290285f, 0.242980f,
+ 0.195090f, 0.146730f, 0.098017f, 0.049068f,
+ 0.000000f, -0.049068f, -0.098017f, -0.146730f,
+ -0.195090f, -0.242980f, -0.290285f, -0.336890f,
+ -0.382683f, -0.427555f, -0.471397f, -0.514103f,
+ -0.555570f, -0.595699f, -0.634393f, -0.671559f,
+ -0.707107f, -0.740951f, -0.773010f, -0.803208f,
+ -0.831470f, -0.857729f, -0.881921f, -0.903989f,
+ -0.923880f, -0.941544f, -0.956940f, -0.970031f,
+ -0.980785f, -0.989177f, -0.995185f, -0.998795f,
+ -1.000000f, -0.998795f, -0.995185f, -0.989177f,
+ -0.980785f, -0.970031f, -0.956940f, -0.941544f,
+ -0.923880f, -0.903989f, -0.881921f, -0.857729f,
+ -0.831470f, -0.803208f, -0.773010f, -0.740951f,
+ -0.707107f, -0.671559f, -0.634393f, -0.595699f,
+ -0.555570f, -0.514103f, -0.471397f, -0.427555f,
+ -0.382683f, -0.336890f, -0.290285f, -0.242980f,
+ -0.195090f, -0.146730f, -0.098017f, -0.049068f,
+};
+
+static float _COS_FULL[128] = {
+ 1.000000f, 0.998795f, 0.995185f, 0.989177f,
+ 0.980785f, 0.970031f, 0.956940f, 0.941544f,
+ 0.923880f, 0.903989f, 0.881921f, 0.857729f,
+ 0.831470f, 0.803208f, 0.773010f, 0.740951f,
+ 0.707107f, 0.671559f, 0.634393f, 0.595699f,
+ 0.555570f, 0.514103f, 0.471397f, 0.427555f,
+ 0.382683f, 0.336890f, 0.290285f, 0.242980f,
+ 0.195090f, 0.146730f, 0.098017f, 0.049068f,
+ 0.000000f, -0.049068f, -0.098017f, -0.146730f,
+ -0.195090f, -0.242980f, -0.290285f, -0.336890f,
+ -0.382683f, -0.427555f, -0.471397f, -0.514103f,
+ -0.555570f, -0.595699f, -0.634393f, -0.671559f,
+ -0.707107f, -0.740951f, -0.773010f, -0.803208f,
+ -0.831470f, -0.857729f, -0.881921f, -0.903989f,
+ -0.923880f, -0.941544f, -0.956940f, -0.970031f,
+ -0.980785f, -0.989177f, -0.995185f, -0.998795f,
+ -1.000000f, -0.998795f, -0.995185f, -0.989177f,
+ -0.980785f, -0.970031f, -0.956940f, -0.941544f,
+ -0.923880f, -0.903989f, -0.881921f, -0.857729f,
+ -0.831470f, -0.803208f, -0.773010f, -0.740951f,
+ -0.707107f, -0.671559f, -0.634393f, -0.595699f,
+ -0.555570f, -0.514103f, -0.471397f, -0.427555f,
+ -0.382683f, -0.336890f, -0.290285f, -0.242980f,
+ -0.195090f, -0.146730f, -0.098017f, -0.049068f,
+ -0.000000f, 0.049068f, 0.098017f, 0.146730f,
+ 0.195090f, 0.242980f, 0.290285f, 0.336890f,
+ 0.382683f, 0.427555f, 0.471397f, 0.514103f,
+ 0.555570f, 0.595699f, 0.634393f, 0.671559f,
+ 0.707107f, 0.740951f, 0.773010f, 0.803208f,
+ 0.831470f, 0.857729f, 0.881921f, 0.903989f,
+ 0.923880f, 0.941544f, 0.956940f, 0.970031f,
+ 0.980785f, 0.989177f, 0.995185f, 0.998795f,
+};
+
+static float STEP = (float)STEP_AMOUNT / 360.0f;
+
+
+static void draw_thick_line(float x1, float y1, float x2, float y2, float thickness) {
+ float rad = atan2f(y2 - y1, x2 - x1);
+
+ float xoffset = -1 * thickness * sinf(rad);
+ if (rad < 0) {
+ xoffset *= -1;
+ }
+ float yoffset = thickness * cosf(rad);
+ if (rad < 0) {
+ yoffset *= -1;
+ }
+
+ /* float xoffset = sqrtf(powf(thickness, 2) * (1.0f - powf(sinf(M_PI / 2 - rad), 2))); */
+ /* float yoffset = thickness * sinf(M_PI / 2 - rad); */
+ /* /\* if (rad < 0) { *\/ */
+ /* xoffset *= -1; */
+ /* yoffset *= -1; */
+ /* } */
+ /* printf("rad: %f, x: %f, y: %f\n", rad, xoffset, yoffset); */
+
+ float x1top = x1 - xoffset;
+ float y1top = y1 - yoffset;
+
+ float x2top = x2 - xoffset;
+ float y2top = y2 - yoffset;
+
+ float x1bottom = x1 + xoffset;
+ float y1bottom = y1 + yoffset;
+
+ float x2bottom = x2 + xoffset;
+ float y2bottom = y2 + yoffset;
+ /* printf("1t: (%f %f) 2t: (%f %f)\n" */
+ /* "1b: (%f %f) 2b: (%f %f)\n", */
+ /* x1top, y1top, */
+ /* x2top, y2top, */
+ /* x1bottom, y1bottom, */
+ /* x2bottom, y2bottom), */
+
+ sgl_v2f(x1top, y1top);
+ sgl_v2f(x1top, y1top);
+ sgl_v2f(x2top, y2top);
+ sgl_v2f(x1bottom, y1bottom);
+ sgl_v2f(x2bottom, y2bottom);
+ sgl_v2f(x2bottom, y2bottom);
+}
+
+static void draw_wave_screen(float x, float y, float h, float w, float *points, size_t len) {
+ float samples_per_px = (float)len / w;
+
+ float last_point = y + points[0] * h;
+ for (int px = 1; px < (int)w; px++) {
+ size_t start = (size_t)(px * samples_per_px);
+ size_t end = (size_t)((px + 1) * samples_per_px);
+ if (end >= len) end = len - 1;
+
+ float minv = 1.0f, maxv = -1.0f;
+ for (size_t i = start; i <= end; i++) {
+ if (points[i] < minv) minv = points[i];
+ if (points[i] > maxv) maxv = points[i];
+ }
+
+ float y_min = y + h * (0.5f - 0.5f * maxv);
+ float y_max = y + h * (0.5f - 0.5f * minv);
+
+ if (y_min == y_max) {
+ printf("%d %f %d %f\n", x + px - 1, last_point, x + px, y_max);
+ draw_thick_line(x + px - 1, last_point, x + px, y_max, 5);
+ last_point = y_max;
+ }
+ }
+}
+
+static void draw_circle(float x, float y, float h, float w, float start_angle, float end_angle) {
+ float c_x = x + w / 2;
+ float c_y = y + h / 2;
+ float r = w > h ? h : w;
+ r /= 2.0f;
+
+ float rad_start = start_angle * (M_PI / 180.0f);
+ float rad_end = end_angle * (M_PI / 180.0f);
+ /* draw_thick_line(c_x, c_y, c_x+(r*cosf(rad_end)), c_y+(r*sinf(rad_end)), 5); */
+
+ int segments = (int)(r * 1.5f);
+ if (segments < 16) {
+ segments = 16;
+ }
+ float angle_step = (rad_end - rad_start) / ((float)segments - 1);
+ float angle;
+
+ sgl_v2f(c_x, c_y);
+ for (int i = 0; i < segments; i++) {
+ angle = rad_start + angle_step * (float)i;
+ sgl_v2f(c_x, c_y);
+ sgl_v2f(c_x+(r*cosf(angle)), c_y+(r*sinf(angle)));
+ }
+ sgl_v2f(c_x+(r*cos(angle)), c_y+(r*sin(angle)));
+}
+
+static void _draw_circle(float x, float y, float h, float w, float start_angle, float end_angle) {
+ float c_x = x + w / 2;
+ float c_y = y + h / 2;
+ float r = w > h ? h : w;
+ r /= 2.0f;
+
+ int start = start_angle * STEP;
+ int end = end_angle * STEP;
+ int amount;
+ if (end_angle == start_angle) {
+ amount = STEP_AMOUNT;
+ } else {
+ amount = (end - start + STEP_AMOUNT) % STEP_AMOUNT;
+ }
+ int idx = start;
+
+
+ sgl_v2f(c_x, c_y);
+ for (int i = 0; i < amount; i++) {
+ sgl_v2f(c_x, c_y);
+ sgl_v2f(c_x+(r*_COS_FULL[idx]), c_y+(r*_SIN_FULL[idx]));
+ idx++;
+ idx %= STEP_AMOUNT;
+ }
+ sgl_v2f(c_x, c_y);
+ sgl_v2f(c_x+(r*_COS_FULL[idx]), c_y+(r*_SIN_FULL[idx]));
+ sgl_v2f(c_x+(r*_COS_FULL[idx]), c_y+(r*_SIN_FULL[idx]));
+}
+
+void handle_custom(Clay_BoundingBox bbox, Clay_CustomRenderData *config) {
+ CustomElementData *custom_data = config->customData;
+
+ switch (custom_data->type) {
+ case CUSTOM_ELEMENT_TYPE_CIRCLE: {
+ CircleData circle_data = custom_data->circle;
+
+ float start_angle = circle_data.start_angle;
+ /* float end_angle = fmod(circle_data.value * 360 + start_angle + 360, 360); */
+ float end_angle = circle_data.value * 360 + start_angle;
+ end_angle = end_angle > start_angle ? end_angle : end_angle + 360;
+
+ sgl_c4f(config->backgroundColor.r / 255.0f,
+ config->backgroundColor.g / 255.0f,
+ config->backgroundColor.b / 255.0f,
+ config->backgroundColor.a / 255.0f);
+
+ sgl_begin_triangle_strip();
+ draw_circle(bbox.x, bbox.y, bbox.height, bbox.width,
+ start_angle, end_angle);
+ sgl_end();
+ break;
+ }
+ case CUSTOM_ELEMENT_TYPE_WAVE_SCREEN: {
+ WaveScreenData wave_data = custom_data->wave_screen;
+ sgl_c4f(config->backgroundColor.r / 255.0f,
+ config->backgroundColor.g / 255.0f,
+ config->backgroundColor.b / 255.0f,
+ config->backgroundColor.a / 255.0f);
+ sgl_begin_triangle_strip();
+ /* draw_thick_line(bbox.x, bbox.y, */
+ /* bbox.x+bbox.width, bbox.y+bbox.height, */
+ /* 20); */
+ draw_wave_screen(bbox.x, bbox.y,
+ bbox.height, bbox.width,
+ wave_data.point_buffer, wave_data.buffer_len);
+ sgl_end();
+
+ }
+ }
+}
diff --git a/src/custom_elements.h b/src/custom_elements.h
new file mode 100644
index 0000000..cd36b6a
--- /dev/null
+++ b/src/custom_elements.h
@@ -0,0 +1,32 @@
+#ifndef CUSTOM_ELEMENTS_H_
+#define CUSTOM_ELEMENTS_H_
+
+#include "clay.h"
+
+typedef enum {
+ CUSTOM_ELEMENT_TYPE_CIRCLE,
+ CUSTOM_ELEMENT_TYPE_WAVE_SCREEN,
+} CustomElementType;
+
+typedef struct {
+ float start_angle;
+ float value;
+} CircleData;
+
+typedef struct {
+ float *point_buffer;
+ size_t buffer_len;
+} WaveScreenData;
+
+typedef struct {
+ CustomElementType type;
+
+ union {
+ CircleData circle;
+ WaveScreenData wave_screen;
+ };
+} CustomElementData;
+
+void handle_custom(Clay_BoundingBox bbox, Clay_CustomRenderData *config);
+
+#endif // CUSTOM_ELEMENTS_H_
diff --git a/src/main.c b/src/main.c
index 1b398d1..7306c28 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,22 +2,32 @@
#include <pthread.h>
#include <stdio.h>
-#define SDL_MAIN_USE_CALLBACKS
-#include <SDL3/SDL.h>
-#include <SDL3/SDL_main.h>
-#include <SDL3/SDL_scancode.h>
-#include <SDL3/SDL_keycode.h>
-
#include "ui.h"
#include "sounds.h"
+#include "custom_elements.h"
+
+#define SOKOL_IMPL
+#define SOKOL_GLCORE
+#include "sokol/sokol_gfx.h"
+#include "sokol/sokol_gl.h"
+#include "sokol/sokol_glue.h"
+#include "sokol/sokol_app.h"
+#include "sokol/sokol_log.h"
+
+#define FONTSTASH_IMPLEMENTATION
+#include "fontstash/fontstash.h"
+#include "sokol/sokol_fontstash.h"
#define CLAY_IMPLEMENTATION
#include "clay.h"
-#include "clay_renderer_SDL3.h"
+
+#define SOKOL_CLAY_IMPL
+#include "sokol/sokol_clay.h"
#define ARENA_IMPLEMENTATION
#include "arena.h"
+
typedef struct {
bool pressed;
@@ -29,8 +39,6 @@ typedef struct {
typedef struct {
- SDL_Window *window;
- Clay_SDL3RendererData renderer_data;
Arena frame_arena;
PointerState pointer;
@@ -43,9 +51,9 @@ typedef struct {
MessageQueue msg_queue;
WaveData wave_data;
pthread_t sound_thread;
-} app_state;
+} AppState;
-int init_sounds(app_state *state) {
+int init_sounds(AppState *state) {
int err;
err =
@@ -159,123 +167,75 @@ int init_sounds(app_state *state) {
return 0;
}
-static inline Clay_Dimensions SDL_MeasureText(Clay_StringSlice text, Clay_TextElementConfig *config, void *userData)
-{
- TTF_Font **fonts = userData;
- TTF_Font *font = fonts[config->fontId];
- int width, height;
-
- TTF_SetFontSize(font, config->fontSize);
- if (!TTF_GetStringSize(font, text.chars, text.length, &width, &height)) {
- SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed to measure text: %s", SDL_GetError());
- }
-
- return (Clay_Dimensions) { (float) width, (float) height };
-}
-
void HandleClayErrors(Clay_ErrorData errorData) {
printf("%s", errorData.errorText.chars);
}
-int init_ui(app_state *state) {
- if (!TTF_Init()) {
- return 1;
- }
-
- if (!SDL_Init(SDL_INIT_VIDEO)) {
- return 1;
- }
-
- if (!SDL_CreateWindowAndRenderer("crynth", DEFAULT_DIMENSIONS_WIDTH, DEFAULT_DIMENSIONS_HEIGHT, SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS, &state->window, &state->renderer_data.renderer)) {
- return 1;
- }
-
- SDL_SetWindowResizable(state->window, true);
-
- state->renderer_data.textEngine = TTF_CreateRendererTextEngine(state->renderer_data.renderer);
- if (!state->renderer_data.textEngine) {
- return 1;
- }
+int init_ui() {
+ sg_setup(&(sg_desc){
+ .environment = sglue_environment(),
+ .logger.func = slog_func,
+ });
+ sgl_setup(&(sgl_desc_t){
+ .logger.func = slog_func,
+ });
+ sclay_setup();
- state->renderer_data.fonts = SDL_calloc(1, sizeof(TTF_Font *));
- if (!state->renderer_data.fonts) {
- return 1;
- }
-
- TTF_Font *font = TTF_OpenFont("resources/Roboto-Regular.ttf", 24);
- if (!font) {
- return 1;
- }
-
- state->renderer_data.fonts[FONT_ID] = font;
+ sclay_add_font("resources/Roboto-Regular.ttf");
+ sclay_set_custom_element_cb(handle_custom);
size_t totalMemorySize = Clay_MinMemorySize();
Clay_Arena clayMemory = (Clay_Arena) {
- .memory = SDL_malloc(totalMemorySize),
+ .memory = malloc(totalMemorySize),
.capacity = totalMemorySize
};
- int width, height;
- SDL_GetWindowSize(state->window, &width, &height);
- Clay_Initialize(clayMemory, (Clay_Dimensions) { (float) width, (float) height }, (Clay_ErrorHandler) { HandleClayErrors, 0});
- Clay_SetMeasureTextFunction(SDL_MeasureText, state->renderer_data.fonts);
+ Clay_Initialize(clayMemory, (Clay_Dimensions) { (float) sapp_width(), (float) sapp_height() }, (Clay_ErrorHandler) { HandleClayErrors, 0});
+ Clay_SetMeasureTextFunction(sclay_measure_text, NULL);
return 0;
}
static KeyState keys[] = {
- {'Z', SDL_SCANCODE_Z, 0, 0}, {'S', SDL_SCANCODE_S, 0, 0},
- {'X', SDL_SCANCODE_X, 0, 0}, {'D', SDL_SCANCODE_D, 0, 0},
- {'C', SDL_SCANCODE_C, 0, 0},
- {'V', SDL_SCANCODE_V, 0, 0}, {'G', SDL_SCANCODE_G, 0, 0},
- {'B', SDL_SCANCODE_B, 0, 0}, {'H', SDL_SCANCODE_H, 0, 0},
- {'N', SDL_SCANCODE_N, 0, 0}, {'J', SDL_SCANCODE_J, 0, 0},
- {'M', SDL_SCANCODE_M, 0, 0},
-
- {'Q', SDL_SCANCODE_Q, 0, 0}, {'2', SDL_SCANCODE_2, 0, 0},
- {'W', SDL_SCANCODE_W, 0, 0}, {'3', SDL_SCANCODE_3, 0, 0},
- {'E', SDL_SCANCODE_E, 0, 0},
- {'R', SDL_SCANCODE_R, 0, 0}, {'6', SDL_SCANCODE_5, 0, 0},
- {'T', SDL_SCANCODE_T, 0, 0}, {'7', SDL_SCANCODE_6, 0, 0},
- {'Y', SDL_SCANCODE_Y, 0, 0}, {'8', SDL_SCANCODE_7, 0, 0},
- {'U', SDL_SCANCODE_U, 0, 0},
+ {'Z', SAPP_KEYCODE_Z, 0, 0}, {'S', SAPP_KEYCODE_S, 0, 0},
+ {'X', SAPP_KEYCODE_X, 0, 0}, {'D', SAPP_KEYCODE_D, 0, 0},
+ {'C', SAPP_KEYCODE_C, 0, 0},
+ {'V', SAPP_KEYCODE_V, 0, 0}, {'G', SAPP_KEYCODE_G, 0, 0},
+ {'B', SAPP_KEYCODE_B, 0, 0}, {'H', SAPP_KEYCODE_H, 0, 0},
+ {'N', SAPP_KEYCODE_N, 0, 0}, {'J', SAPP_KEYCODE_J, 0, 0},
+ {'M', SAPP_KEYCODE_M, 0, 0},
+
+ {'Q', SAPP_KEYCODE_Q, 0, 0}, {'2', SAPP_KEYCODE_2, 0, 0},
+ {'W', SAPP_KEYCODE_W, 0, 0}, {'3', SAPP_KEYCODE_3, 0, 0},
+ {'E', SAPP_KEYCODE_E, 0, 0},
+ {'R', SAPP_KEYCODE_R, 0, 0}, {'6', SAPP_KEYCODE_5, 0, 0},
+ {'T', SAPP_KEYCODE_T, 0, 0}, {'7', SAPP_KEYCODE_6, 0, 0},
+ {'Y', SAPP_KEYCODE_Y, 0, 0}, {'8', SAPP_KEYCODE_7, 0, 0},
+ {'U', SAPP_KEYCODE_U, 0, 0},
};
-SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
- (void) argc;
- (void) argv;
-
- app_state *state = malloc(sizeof(app_state));
- memset(state, 0, sizeof(app_state));
- *appstate = state;
+static void init(void *app_state) {
+ AppState *state = app_state;
state->keys = keys;
state->keys_amount = sizeof(keys)/sizeof(keys[0]);
- if (init_ui(state) != 0) {
- printf("Couldn't initialize UI: %s", SDL_GetError());
- return SDL_APP_FAILURE;
+ if (init_ui() != 0) {
+ printf("Couldn't initialize UI");
+ sapp_quit();
}
if (init_sounds(state) != 0) {
- return SDL_APP_FAILURE;
+ printf("Couldn't initialize sounds: %s");
+ sapp_quit();
}
-
- return SDL_APP_CONTINUE;
}
float old_wave_buffer[DISPLAY_SAMPLES];
-SDL_AppResult SDL_AppIterate(void *appstate) {
- app_state *state = appstate;
- Arena *arena = &state->frame_arena;
- arena_reset(arena);
-
- int start_tick = SDL_GetTicks();
-
+void fill_ui_data(UIData *ui_data, AppState *state) {
Clay_Dimensions dimensions = Clay_GetCurrentContext()->layoutDimensions;
- UIData *ui_data = arena_alloc(arena, sizeof(UIData));
- ui_data->arena = arena;
+ ui_data->arena = &state->frame_arena;
ui_data->msg_queue = &state->msg_queue;
int read_index = 1 - atomic_load(&state->wave_data.write_index);
@@ -283,7 +243,7 @@ SDL_AppResult SDL_AppIterate(void *appstate) {
size_t buffer_start = 0;
for (size_t i = 1; i < DISPLAY_SAMPLES; i++) {
- if (wave_buffer[i-1] < 0 && wave_buffer[i] >= 0) {
+ if (wave_buffer[i-1] < 0 && wave_buffer[i] >= 0) {
buffer_start = i;
break;
}
@@ -303,46 +263,51 @@ SDL_AppResult SDL_AppIterate(void *appstate) {
ui_data->knob_settings = &state->knob_settings;
ui_data->scale = dimensions.width / DEFAULT_DIMENSIONS_WIDTH;
+}
-
- Clay_SetPointerState((Clay_Vector2){ state->pointer.position_x, state->pointer.position_y }, state->pointer.pressed);
- Clay_UpdateScrollContainers(true, (Clay_Vector2){ state->pointer.pending_scroll_delta_x, state->pointer.pending_scroll_delta_y }, 0.016f);
- state->pointer.pending_scroll_delta_x = 0;
- state->pointer.pending_scroll_delta_y = 0;
+static void frame(void *app_state) {
+ AppState *state = app_state;
+ Arena *arena = &state->frame_arena;
+ arena_reset(arena);
+ UIData *ui_data = arena_alloc(arena, sizeof(UIData));
+ fill_ui_data(ui_data, state);
+
+
+ sclay_new_frame();
Clay_BeginLayout();
draw_ui(ui_data);
Clay_RenderCommandArray render_commands = Clay_EndLayout();
- SDL_SetRenderDrawColor(state->renderer_data.renderer, 0, 0, 0, 255);
- SDL_RenderClear(state->renderer_data.renderer);
- SDL_Clay_RenderClayCommands(&state->renderer_data, &render_commands);
+ sg_begin_pass(&(sg_pass){ .swapchain = sglue_swapchain() });
+
+ sgl_matrix_mode_modelview();
+ sgl_load_identity();
- SDL_RenderPresent(state->renderer_data.renderer);
+ sclay_render(render_commands, NULL);
- int end_tick = SDL_GetTicks();
- int frame_ticks = end_tick - start_tick;
+ sgl_draw();
+ sg_end_pass();
+ sg_commit();
- if (frame_ticks < SCREEN_TICKS_PER_FRAME) {
- SDL_Delay(SCREEN_TICKS_PER_FRAME - frame_ticks);
- }
+ /* int end_tick = SDL_GetTicks(); */
+ /* int frame_ticks = end_tick - start_tick; */
- return SDL_APP_CONTINUE;
+ /* if (frame_ticks < SCREEN_TICKS_PER_FRAME) { */
+ /* SDL_Delay(SCREEN_TICKS_PER_FRAME - frame_ticks); */
+ /* } */
}
-SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) {
- app_state *state = appstate;
+static void event(const sapp_event* event, void *app_state) {
+ AppState *state = app_state;
switch (event->type) {
- case SDL_EVENT_QUIT: {
- return SDL_APP_SUCCESS;
- }
- case SDL_EVENT_KEY_DOWN: {
+ case SAPP_EVENTTYPE_KEY_DOWN: {
for (size_t i = 0; i < state->keys_amount; i++) {
- if (event->key.scancode == state->keys[i].keycode) {
+ if (event->key_code == state->keys[i].keycode) {
if (state->keys[i].keyboard_pressed) {
break;
}
@@ -357,9 +322,9 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) {
break;
}
- case SDL_EVENT_KEY_UP: {
+ case SAPP_EVENTTYPE_KEY_UP: {
for (size_t i = 0; i < state->keys_amount; i++) {
- if (event->key.scancode == state->keys[i].keycode) {
+ if (event->key_code == state->keys[i].keycode) {
if (!state->keys[i].keyboard_pressed) {
break;
}
@@ -373,50 +338,33 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) {
break;
}
- case SDL_EVENT_WINDOW_RESIZED:
- Clay_SetLayoutDimensions((Clay_Dimensions) { (float) event->window.data1, (float) event->window.data2 });
- break;
-
- case SDL_EVENT_MOUSE_MOTION:
- state->pointer.pressed = event->motion.state & SDL_BUTTON_LMASK;
- state->pointer.position_x = event->motion.x;
- state->pointer.position_y = event->motion.y;
- break;
-
- case SDL_EVENT_MOUSE_BUTTON_DOWN:
- state->pointer.pressed = event->button.button == SDL_BUTTON_LEFT;
- state->pointer.position_x = event->button.x;
- state->pointer.position_y = event->button.y;
- break;
- case SDL_EVENT_MOUSE_BUTTON_UP:
- if (event->button.button == SDL_BUTTON_LEFT) {
- state->pointer.pressed = false;
- state->pointer.position_x = event->button.x;
- state->pointer.position_y = event->button.y;
- }
- break;
-
- case SDL_EVENT_MOUSE_WHEEL:
- state->pointer.pending_scroll_delta_x += event->wheel.x;
- state->pointer.pending_scroll_delta_y += event->wheel.y;
- break;
-
default:
+ sclay_handle_event(event);
break;
}
- return SDL_APP_CONTINUE;
}
-void SDL_AppQuit(void *appstate, SDL_AppResult result) {
- (void) result;
-
- app_state *state = appstate;
-
- MessageQueue *queue = &state->msg_queue;
+static void cleanup() {
+ sclay_shutdown();
+ sgl_shutdown();
+ sg_shutdown();
+}
- SynthMessage stop_msg = {.type = MSG_STOP};
- mqueue_push(queue, stop_msg);
+sapp_desc sokol_main(int argc, char **argv) {
+ (void)argc;
+ (void)argv;
- pthread_join(state->sound_thread, NULL);
- check(snd_pcm_close(state->sound_device));
+ AppState *state = malloc(sizeof(AppState));
+
+ return (sapp_desc){
+ .user_data = state,
+ .init_userdata_cb = init,
+ .frame_userdata_cb = frame,
+ .event_userdata_cb = event,
+ .cleanup_cb = cleanup,
+ .window_title = "crynth",
+ .width = DEFAULT_DIMENSIONS_WIDTH,
+ .height = DEFAULT_DIMENSIONS_HEIGHT,
+ .logger.func = slog_func,
+ };
}
diff --git a/src/ui.c b/src/ui.c
index 1ab15ab..10f4c64 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -13,14 +13,14 @@ float point_angle_on_circle(Clay_Vector2 point, Clay_BoundingBox circle) {
float center_x = circle.x + circle.width / 2;
float center_y = circle.y + circle.width / 2;
- float point_rad = SDL_atan2f(point.y - center_y, point.x - center_x);
+ float point_rad = atan2f(point.y - center_y, point.x - center_x);
- return point_rad * 180.0f / SDL_PI_F;
+ return point_rad * 180.0f / M_PI;
}
float point_value_on_circle(Clay_Vector2 point, Clay_BoundingBox circle, float start_angle) {
float point_on_circle = point_angle_on_circle(point, circle);
- float value = SDL_fmodf((point_on_circle - start_angle + 360), 360) / 360;
+ float value = fmodf((point_on_circle - start_angle + 360), 360) / 360;
return value;
}
@@ -170,9 +170,9 @@ void draw_black_key(size_t idx, UIData *ui_data) {
.element = CLAY_ATTACH_POINT_CENTER_TOP,
.parent = CLAY_ATTACH_POINT_RIGHT_TOP,
},
- .offset = {
- .y = -1,
- },
+ /* .offset = { */
+ /* .y = -1, */
+ /* }, */
},
}) {
bool mouse_pressed = ui_data->keys[idx].mouse_pressed;
@@ -261,13 +261,13 @@ void draw_knob(Clay_ElementId id, UIData *ui_data, KnobInfo* knob_info, Clay_Siz
knob_element_data->circle = (CircleData){
.start_angle = -90,
.value = value,
- .color = hovered ? COLOR_FG_INTER : COLOR_FG,
};
CLAY_AUTO_ID({
.layout = {
.sizing = {outer_size, outer_size},
.childAlignment = {CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER},
},
+ .backgroundColor = hovered ? COLOR_FG_INTER : COLOR_FG,
.custom = {
.customData = knob_element_data,
},
@@ -277,12 +277,12 @@ void draw_knob(Clay_ElementId id, UIData *ui_data, KnobInfo* knob_info, Clay_Siz
inner_data->circle = (CircleData){
.start_angle = 0,
.value = 1.0f,
- .color = COLOR_ACCENT,
};
CLAY_AUTO_ID({
.layout = {
.sizing = {inner_size, inner_size},
},
+ .backgroundColor = COLOR_ACCENT,
.custom = {
.customData = inner_data,
},
@@ -298,13 +298,13 @@ void draw_screen(UIData *ui_data) {
wave->wave_screen = (WaveScreenData){
.point_buffer = ui_data->wave_buffer,
.buffer_len = ui_data->wave_buffer_size,
- .color = COLOR_FG,
};
CLAY(CLAY_ID("wave_screen"), {
.layout = {
.sizing = {CLAY_SIZING_FIXED(200 * ui_data->scale), CLAY_SIZING_FIXED(100 * ui_data->scale)},
},
+ .backgroundColor = COLOR_FG,
.border = { .width = {1, 1, 1, 1, 0}, .color = COLOR_FG },
.custom = {
.customData = wave,
diff --git a/src/ui.h b/src/ui.h
index d9ecbf4..bfae0c0 100644
--- a/src/ui.h
+++ b/src/ui.h
@@ -4,13 +4,12 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
-
-#include <SDL3/SDL_scancode.h>
-#include <SDL3/SDL_keycode.h>
+#include <math.h>
#include "arena.h"
+#include "sokol/sokol_app.h"
-#include "clay_renderer_SDL3.h"
+#include "custom_elements.h"
#include "clay.h"
#include "messages.h"
@@ -24,7 +23,7 @@ static const Clay_Color COLOR_ACCENT = (Clay_Color){133, 146, 137, 255};
typedef struct {
char letter;
- SDL_Keycode keycode;
+ sapp_keycode keycode;
bool mouse_pressed;
bool keyboard_pressed;
} KeyState;