From 1d30dba681e330f05ff8c7ec99dcdbc98885e75a Mon Sep 17 00:00:00 2001 From: Sheldon Lee Date: Fri, 8 Nov 2024 22:46:33 +0800 Subject: [PATCH] Refactor texture code + start splitting networking into threads. --- main.c | 116 ++++++++++++++++++++++++++++++++++-------------------- texture.c | 40 +++++++++++++++++-- texture.h | 13 +++++- 3 files changed, 121 insertions(+), 48 deletions(-) diff --git a/main.c b/main.c index 9ddb52f..c45f4b0 100644 --- a/main.c +++ b/main.c @@ -2,6 +2,9 @@ #include #include +#include +#include + #include "texture.h" #include "audio.h" #include "net.h" @@ -9,15 +12,18 @@ #define SCREEN_WIDTH 640 #define SCREEN_HEIGHT 480 +#define TEXT_LINES 20 +#define BODY_TEXT_LINES TEXT_LINES-2 +#define FONT_SIZE SCREEN_HEIGHT/TEXT_LINES #define PORT 55555 typedef enum { + SOCKET_LISTEN, SELECTING_DEVICE, RECORDING, RECORDED, PLAYBACK, - SOCKET, } application_state; typedef struct { @@ -25,6 +31,7 @@ typedef struct { audio_state audio; int device_index; int update_ui; + sem_t sem; } state; int init(); @@ -32,6 +39,8 @@ void destroy(); int select_device(SDL_KeyboardEvent* key_event, int max_index); void application_state_to_string(application_state state, char* string); +void* peer_discovery_t(void* args); + SDL_Window* window = NULL; SDL_Renderer* renderer = NULL; @@ -39,6 +48,7 @@ int num_devices = 0; int handle_input(SDL_Event* event, state* state); void handle_task(state* state); +void render_body_text(text_texture* textures, int len); int main(int argc, char* argv[]) { if (!init()) return 1; @@ -46,33 +56,43 @@ int main(int argc, char* argv[]) num_devices = SDL_GetNumAudioDevices(1); log_message(LOG_INFO, "Num audio devices: %i", num_devices); char char_buffer[64]; - char default_fmt[] = "Device selected: %i"; + char device_selected_fmt[] = "Device selected: %i"; state state; - state.application_state = SOCKET; + //state.application_state = SOCKET_LISTEN; + state.application_state = SELECTING_DEVICE; if (!audio_init(&state.audio)) return 1; state.device_index = -1; state.update_ui = 0; + sem_init(&state.sem, 0, 1); text_texture display_text_texture; - text_texture_init(&display_text_texture, renderer); - sprintf(char_buffer, default_fmt, state.device_index); + text_texture_init(&display_text_texture, renderer, FONT_SIZE); + sprintf(char_buffer, device_selected_fmt, state.device_index); text_texture_load(&display_text_texture, char_buffer); - text_texture device_textures[num_devices]; - for (int i = 0; i < num_devices; i++) { - text_texture_init(&device_textures[i], renderer); - sprintf(char_buffer, "%i: %s", i, SDL_GetAudioDeviceName(i, 1)); - text_texture_load(&device_textures[i], char_buffer); - } - text_texture state_text_texture; - text_texture_init(&state_text_texture, renderer); + text_texture_init(&state_text_texture, renderer, FONT_SIZE); application_state_to_string(state.application_state, char_buffer); text_texture_load(&state_text_texture, char_buffer); + text_texture_frame socket_frame; + text_texture_frame_init(&socket_frame, BODY_TEXT_LINES, renderer, FONT_SIZE); + + text_texture_frame select_device_frame; + text_texture_frame_init(&select_device_frame, num_devices, renderer, FONT_SIZE); + + for (int i = 0; i < select_device_frame.len; i++) { + sprintf(char_buffer, "%i: %s", i, SDL_GetAudioDeviceName(i, 1)); + text_texture_load(&select_device_frame.textures[i], char_buffer); + } + + pthread_t peer_discovery_thread; + pthread_create(&peer_discovery_thread, NULL, peer_discovery_t, &state); + SDL_Event event; while (1) { + sem_wait(&state.sem); while (SDL_PollEvent(&event)) { SDL_Keycode keysym = event.key.keysym.sym; switch (event.type) { @@ -91,7 +111,7 @@ int main(int argc, char* argv[]) handle_task(&state); if (state.update_ui) { - sprintf(char_buffer, default_fmt, state.device_index); + sprintf(char_buffer, device_selected_fmt, state.device_index); text_texture_load(&display_text_texture, char_buffer); application_state_to_string(state.application_state, char_buffer); text_texture_load(&state_text_texture, char_buffer); @@ -106,29 +126,29 @@ int main(int argc, char* argv[]) // Render text_texture_render(&display_text_texture, 0, 0); + if (state.application_state == SOCKET_LISTEN) { + text_texture_frame_render(&socket_frame, 0, FONT_SIZE); + } + if (state.application_state == SELECTING_DEVICE) { - int text_y_offset_step = display_text_texture.height * 2; - int text_y_offset = text_y_offset_step; - for (int i = 0; i < num_devices; i++) { - text_texture_render(&device_textures[i], 0, text_y_offset); - text_y_offset += text_y_offset_step; - } + text_texture_frame_render(&select_device_frame, 0, FONT_SIZE); } text_texture_render(&state_text_texture, 0, SCREEN_HEIGHT - state_text_texture.height); // Update the screen SDL_RenderPresent(renderer); + sem_post(&state.sem); } cleanup: log_message(LOG_INFO, "Cleanup start"); audio_destroy(&state.audio); log_message(LOG_INFO, "Audio done"); - text_texture_free(&display_text_texture); - for (int i = 0; i < num_devices; i++) { - text_texture_free(&device_textures[i]); - } + text_texture_destroy(&display_text_texture); + text_texture_destroy(&state_text_texture); + text_texture_frame_destroy(&socket_frame); + text_texture_frame_destroy(&select_device_frame); log_message(LOG_INFO, "Texture done"); destroy(); log_message(LOG_INFO, "Done"); @@ -140,6 +160,18 @@ int handle_input(SDL_Event* event, state* state) SDL_Keycode keysym = event->key.keysym.sym; switch (state->application_state) { + case SOCKET_LISTEN: + switch (keysym) { + case SDLK_1: + log_message(LOG_INFO, "Socket button 1 pressed"); + net_broadcast(); + break; + case SDLK_2: + log_message(LOG_INFO, "Socket button 2 pressed"); + break; + } + break; + case SELECTING_DEVICE: switch (keysym) { case SDLK_y: @@ -163,7 +195,6 @@ int handle_input(SDL_Event* event, state* state) audio_device_close(&state->audio, 1); audio_recording_init(&state->audio, state->device_index); state->update_ui = 1; - break; case RECORDING: @@ -207,17 +238,6 @@ int handle_input(SDL_Event* event, state* state) } break; - case SOCKET: - switch (keysym) { - case SDLK_1: - log_message(LOG_INFO, "Socket button 1 pressed"); - net_broadcast(); - break; - case SDLK_2: - log_message(LOG_INFO, "Socket button 2 pressed"); - net_listen_clients(); - break; - } } return 1; } @@ -226,6 +246,9 @@ void handle_task(state* state) { switch (state->application_state) { + case SOCKET_LISTEN: + break; + case SELECTING_DEVICE: break; @@ -246,8 +269,6 @@ void handle_task(state* state) } break; - case SOCKET: - break; } } @@ -318,8 +339,11 @@ int select_device(SDL_KeyboardEvent* key_event, int max_index) void application_state_to_string(application_state state, char* string) { switch (state) { + case SOCKET_LISTEN: + sprintf(string, "Socket"); + break; case SELECTING_DEVICE: - sprintf(string, "Selecting Device [0-9] -> [y/RET], "); + sprintf(string, "Selecting Device [0-9] -> [y/RET]"); break; case RECORDING: sprintf(string, "Recording [ESC]: CANCEL"); @@ -330,8 +354,16 @@ void application_state_to_string(application_state state, char* string) case PLAYBACK: sprintf(string, "Playing [ESC]: CANCEL"); break; - case SOCKET: - sprintf(string, "Socket"); - break; + } +} + +void* peer_discovery_t(void* args) +{ + state* state = args; + while (1) { + sem_wait(&state->sem); + net_listen_clients(); + sem_post(&state->sem); + sleep(1); } } diff --git a/texture.c b/texture.c index b6de90e..eaca8d4 100644 --- a/texture.c +++ b/texture.c @@ -1,11 +1,11 @@ #include "texture.h" #include "log.h" -int text_texture_init(text_texture* text_texture, SDL_Renderer* renderer) +int text_texture_init(text_texture* text_texture, SDL_Renderer* renderer, int font_size) { text_texture->texture = NULL; text_texture->renderer = renderer; - text_texture->font = TTF_OpenFont("FiraCode-Regular.ttf", 24); + text_texture->font = TTF_OpenFont("FiraCode-Regular.ttf", font_size); if (!text_texture->font) { log_message(LOG_ERROR, "Failed to load font! TTF_Error: %s", TTF_GetError()); return 0; @@ -23,6 +23,7 @@ int text_texture_load(text_texture* text_texture, char* string) } SDL_Color text_color = { 255, 255, 255 }; + if (strlen(string) == 0) string = " "; SDL_Surface* text_surface = TTF_RenderText_Solid(text_texture->font, string, text_color); if (!text_surface) { log_message(LOG_ERROR, "Unable to render text surface! TTF_Error: %s", TTF_GetError()); @@ -35,7 +36,7 @@ int text_texture_load(text_texture* text_texture, char* string) return 0; } - text_texture->texture = SDL_CreateTextureFromSurface(text_texture->renderer, text_surface); + text_texture->texture = texture; text_texture->width = text_surface->w; text_texture->height = text_surface->h; @@ -62,11 +63,42 @@ int text_texture_render(text_texture* text_texture, int x, int y) return 1; } -int text_texture_free(text_texture* text_texture) +int text_texture_destroy(text_texture* text_texture) { if (!text_texture->texture) { return 0; } SDL_DestroyTexture(text_texture->texture); + TTF_CloseFont(text_texture->font); + return 1; +} + +int text_texture_frame_init(text_texture_frame* text_texture_frame, int len, SDL_Renderer* renderer, int font_size) +{ + text_texture_frame->textures = malloc(len*sizeof(text_texture)); + for (int i = 0; i < len; i++) { + text_texture_init(&text_texture_frame->textures[i], renderer, font_size); + } + text_texture_frame->len = len; + return 1; +} + +int text_texture_frame_render(text_texture_frame* text_texture_frame, int x, int y) +{ + int text_y_offset_step = TTF_FontHeight(text_texture_frame->textures[0].font); + int text_y_offset = y; + for (int i = 0; i < text_texture_frame->len; i++) { + text_texture_render(&text_texture_frame->textures[i], x, text_y_offset); + text_y_offset += text_y_offset_step; + } + return 1; +} + +int text_texture_frame_destroy(text_texture_frame* text_texture_frame) +{ + for (int i = 0; i < text_texture_frame->len; i++) { + text_texture_destroy(&text_texture_frame->textures[i]); + } + free(text_texture_frame->textures); return 1; } diff --git a/texture.h b/texture.h index aa9be5f..96c39df 100644 --- a/texture.h +++ b/texture.h @@ -12,9 +12,18 @@ typedef struct { int height; } text_texture; -int text_texture_init(text_texture* text_texture, SDL_Renderer* renderer); +typedef struct { + text_texture* textures; + int len; +} text_texture_frame; + +int text_texture_init(text_texture* text_texture, SDL_Renderer* renderer, int font_size); int text_texture_load(text_texture* text_texture, char* string); int text_texture_render(text_texture* text_texture, int x, int y); -int text_texture_free(text_texture* text_texture); +int text_texture_destroy(text_texture* text_texture); + +int text_texture_frame_init(text_texture_frame* text_texture_frame, int len, SDL_Renderer* renderer, int font_size); +int text_texture_frame_render(text_texture_frame* text_texture_frame, int x, int y); +int text_texture_frame_destroy(text_texture_frame* text_texture_frame); #endif