diff options
Diffstat (limited to 'src/main.c')
| -rw-r--r-- | src/main.c | 270 |
1 files changed, 109 insertions, 161 deletions
@@ -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, + }; } |
