From fc326115fa154bc19f3f10d7c2c4e57710ef1e0d Mon Sep 17 00:00:00 2001 From: spl3g Date: Sun, 9 Nov 2025 20:43:50 +0300 Subject: Move to sokol (broke the wave screen) --- src/clay_renderer_SDL3.c | 347 ----------------------------------------------- src/clay_renderer_SDL3.h | 43 ------ src/custom_elements.c | 255 ++++++++++++++++++++++++++++++++++ src/custom_elements.h | 32 +++++ src/main.c | 270 +++++++++++++++--------------------- src/ui.c | 18 +-- src/ui.h | 9 +- 7 files changed, 409 insertions(+), 565 deletions(-) delete mode 100644 src/clay_renderer_SDL3.c delete mode 100644 src/clay_renderer_SDL3.h create mode 100644 src/custom_elements.c create mode 100644 src/custom_elements.h (limited to 'src') 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 - -/* 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, ¤tClippingRectangle); - 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 -#include -#include - -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 +#include + +#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 #include -#define SDL_MAIN_USE_CALLBACKS -#include -#include -#include -#include - #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 #include #include - -#include -#include +#include #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; -- cgit v1.2.3